From 7e01ec51e7002d0ec343730e5bbb110c47e84e5f Mon Sep 17 00:00:00 2001 From: Devin Date: Mon, 20 Jul 2026 22:06:42 +0000 Subject: [PATCH 1/2] Add NOT_GIVEN sentinel for nullable optional params Adds the NotGiven type and NOT_GIVEN sentinel to the hand-maintained _types module. Generated methods use it as the default for nullable optional params so an omitted argument (leave unchanged) is distinguishable from an explicit None (clear via JSON null). The generated signatures arrive via regeneration from oagen-emitters#189. --- src/workos/_types.py | 20 +++++++++++++++++++- tests/test_types.py | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/test_types.py diff --git a/src/workos/_types.py b/src/workos/_types.py index 3ae131ec..ece7b179 100644 --- a/src/workos/_types.py +++ b/src/workos/_types.py @@ -5,7 +5,7 @@ import sys from datetime import datetime from enum import Enum -from typing import Any, Dict, NoReturn, Protocol, TypedDict, TypeVar +from typing import Any, Dict, Literal, NoReturn, Protocol, TypedDict, TypeVar if sys.version_info >= (3, 11): from typing import Self @@ -35,6 +35,24 @@ def enum_value(value: Any) -> Any: return value.value if isinstance(value, Enum) else value +class NotGiven: + """Sentinel used as the default for nullable optional parameters. + + Distinguishes an omitted argument ("leave unchanged", not sent) from an + explicit ``None``, which clears the field by sending JSON ``null``. + Falsy so ``if not param`` reads naturally. + """ + + def __bool__(self) -> Literal[False]: + return False + + def __repr__(self) -> str: + return "NOT_GIVEN" + + +NOT_GIVEN = NotGiven() + + D = TypeVar("D", bound=Deserializable) diff --git a/tests/test_types.py b/tests/test_types.py new file mode 100644 index 00000000..4c770253 --- /dev/null +++ b/tests/test_types.py @@ -0,0 +1,18 @@ +from workos._types import NOT_GIVEN, NotGiven + + +class TestNotGiven: + """The NOT_GIVEN sentinel is the default for nullable optional params, + letting generated methods tell an omitted argument apart from an explicit + None (which clears the field via JSON null).""" + + def test_is_falsy(self): + assert not NOT_GIVEN + assert bool(NOT_GIVEN) is False + + def test_repr(self): + assert repr(NOT_GIVEN) == "NOT_GIVEN" + + def test_is_distinct_from_none(self): + assert NOT_GIVEN is not None + assert isinstance(NOT_GIVEN, NotGiven) From 3ae9506947305b94ddec6174a87c9bba6dfcfc11 Mon Sep 17 00:00:00 2001 From: Devin Date: Mon, 20 Jul 2026 22:10:13 +0000 Subject: [PATCH 2/2] Export NOT_GIVEN and NotGiven from public namespace --- src/workos/__init__.py | 4 +++- tests/test_types.py | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/workos/__init__.py b/src/workos/__init__.py index a6f03134..faa676ad 100644 --- a/src/workos/__init__.py +++ b/src/workos/__init__.py @@ -16,7 +16,7 @@ ) from ._pagination import AsyncPage, ListMetadata, SyncPage from .public_client import create_public_client -from ._types import RequestOptions +from ._types import NOT_GIVEN, NotGiven, RequestOptions __all__ = [ "WorkOSClient", @@ -34,5 +34,7 @@ "AsyncPage", "ListMetadata", "RequestOptions", + "NOT_GIVEN", + "NotGiven", "create_public_client", ] diff --git a/tests/test_types.py b/tests/test_types.py index 4c770253..cf937083 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -16,3 +16,9 @@ def test_repr(self): def test_is_distinct_from_none(self): assert NOT_GIVEN is not None assert isinstance(NOT_GIVEN, NotGiven) + + def test_exported_from_public_namespace(self): + import workos + + assert workos.NOT_GIVEN is NOT_GIVEN + assert workos.NotGiven is NotGiven