From c79c5dcb066e18a24b42a29f5c520bf882841a2f Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Sun, 24 Aug 2025 15:14:18 -0400 Subject: [PATCH 1/2] Dogfood PEP 661 Sentinel --- src/typing_extensions.py | 79 ++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 43 deletions(-) diff --git a/src/typing_extensions.py b/src/typing_extensions.py index 77f33e16..5bb94d33 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -160,17 +160,48 @@ # Added with bpo-45166 to 3.10.1+ and some 3.9 versions _FORWARD_REF_HAS_CLASS = "__forward_is_class__" in typing.ForwardRef.__slots__ -# The functions below are modified copies of typing internal helpers. -# They are needed by _ProtocolMeta and they provide support for PEP 646. +class Sentinel: + """Create a unique sentinel object. + + *name* should be the name of the variable to which the return value shall be assigned. + *repr*, if supplied, will be used for the repr of the sentinel object. + If not provided, "" will be used. + """ + + def __init__( + self, + name: str, + repr: typing.Optional[str] = None, + ): + self._name = name + self._repr = repr if repr is not None else f'<{name}>' -class _Sentinel: def __repr__(self): - return "" + return self._repr + + if sys.version_info < (3, 11): + # The presence of this method convinces typing._type_check + # that Sentinels are types. + def __call__(self, *args, **kwargs): + raise TypeError(f"{type(self).__name__!r} object is not callable") + # Breakpoint: https://github.com/python/cpython/pull/21515 + if sys.version_info >= (3, 10): + def __or__(self, other): + return typing.Union[self, other] + + def __ror__(self, other): + return typing.Union[other, self] + + def __getstate__(self): + raise TypeError(f"Cannot pickle {type(self).__name__!r} object") -_marker = _Sentinel() +_marker = Sentinel("_marker") + +# The functions below are modified copies of typing internal helpers. +# They are needed by _ProtocolMeta and they provide support for PEP 646. # Breakpoint: https://github.com/python/cpython/pull/27342 if sys.version_info >= (3, 10): @@ -4207,44 +4238,6 @@ def evaluate_forward_ref( ) -class Sentinel: - """Create a unique sentinel object. - - *name* should be the name of the variable to which the return value shall be assigned. - - *repr*, if supplied, will be used for the repr of the sentinel object. - If not provided, "" will be used. - """ - - def __init__( - self, - name: str, - repr: typing.Optional[str] = None, - ): - self._name = name - self._repr = repr if repr is not None else f'<{name}>' - - def __repr__(self): - return self._repr - - if sys.version_info < (3, 11): - # The presence of this method convinces typing._type_check - # that Sentinels are types. - def __call__(self, *args, **kwargs): - raise TypeError(f"{type(self).__name__!r} object is not callable") - - # Breakpoint: https://github.com/python/cpython/pull/21515 - if sys.version_info >= (3, 10): - def __or__(self, other): - return typing.Union[self, other] - - def __ror__(self, other): - return typing.Union[other, self] - - def __getstate__(self): - raise TypeError(f"Cannot pickle {type(self).__name__!r} object") - - if sys.version_info >= (3, 14, 0, "beta"): type_repr = annotationlib.type_repr else: From 069030e48ea1ba12df17ab74d523f8e5cc92a0de Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Mon, 25 Aug 2025 10:16:40 -0400 Subject: [PATCH 2/2] Update src/typing_extensions.py Co-authored-by: Alex Waygood --- src/typing_extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/typing_extensions.py b/src/typing_extensions.py index 5bb94d33..c2ecc2fc 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -198,7 +198,7 @@ def __getstate__(self): raise TypeError(f"Cannot pickle {type(self).__name__!r} object") -_marker = Sentinel("_marker") +_marker = Sentinel("sentinel") # The functions below are modified copies of typing internal helpers. # They are needed by _ProtocolMeta and they provide support for PEP 646.