You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Adapt Sentinel implementation to accepted version of PEP 661 #742
PEP-661 was accepted, but it is implemented a little differently than our typing_extensions.Sentinel. Let's see how we can make the typing-extensions version better match the version that will be in Python 3.15, while keeping backward compatibility for users who may already be using typing_extensions.Sentinel.
Here are the relevant differences:
We have typing_extensions.Sentinel; 3.15 will have builtins.sentinel (lowercase). Let's not worry about the name. On Python 3.15 we'll re-export builtins.sentinel as typing_extensions.Sentinel.
Our Sentinel is subclassable; builtins.sentinel will not be. Let's add an __init_subclass__ that emits a DeprecationWarning.
We added an extra repr argument to control the repr. Let's emit a DeprecationWarning if it is passed.
The default repr is different: <name> for us, just name for the builtin. Let's just change this.
We made our Sentinel not picklable; the builtin is picklable by name. So let's add a __module__ attribute inferred from the caller (can reuse _set_module) and a __reduce__ that just returns self.__name__.
The builtin doesn't support weakrefs; our version does because it's in Python. I don't know of a way to deprecate our support, so let's just document this difference.
The builtin exposes a __name__ attribute; we have _name. Again let's just change this.
There are some observable changes from the builtin being in C (e.g., the type is immutable), but let's not worry about that.
There are three open PRs about changing Sentinel. #715 and #732 make changes that introduce further incompatibilities, so I'm going to close those. #617 goes in the right direction but also introduces some further incompatible changes.
builtins.sentinel will raise TypeError on a non-string name; we accept it. Let's also raise DeprecationWarning for this.
The name argument to builtins.sentinel will be positional only, but we currently accept it as a keyword arg. I think we can also DeprecationWarning this, though we'll have to complicate the signature a bit.
builtins.sentinel has __copy__ returning itself, we don't.
The current implementation also allows setting arbitrary instance attributes. See if we can DeprecationWarning this (in __setattr__ maybe?).
Renaming and deprecating a class name is difficult. I've made an attempt but I'm unsure if a perfect solution is possible.
builtins.sentinel has __copy__ returning itself, we don't.
When __reduce__ is used for singletons then copies will automatically reuse the objects identity. I've included tests for this.
builtins.sentinel will raise TypeError on a non-string name; we accept it.
The parameter is name: str which means we already don't accept non-strings even if they might pass at runtime. The purpose of type checking is to resolve these issues before they occur at runtime.
We don't need to deprecate the class itself, just some particular behaviors. In the future we can indefinitely keep re-exporting builtins.sentinel as typing_extensions.Sentinel.
Using the correct name is important. Switching from typing_extensions to native Python and backporting to older versions should be a simple addition or removal of from typing_extensions import sentinel. Using Sentinel with the wrong case needs to be actively discouraged or else things will get worse for code migration.
I can understand keeping Sentinel available because people would've used it by this point and thus it has to stick around forever. Though I'd prefer if typeshed deprecated it in favor of sentinel, linters will probably start doing that by themselves.
What I really wonder is if anybody actually made weakrefs to it or added custom attributes. Otherwise I could've added a simple __slots__ to the implementation.
typing-extensions is very widely used and backwards compatibility is important, so we generally have to assume that people have done all of those things.
For what it's worth, when I was implementing PEP-695 in Python, I initially made it so you could no longer assign custom attributes to TypeVar instances, and it broke some things. Similarly, we got bug reports when I accidentally made TypeVars (and I think also unions?) not weakrefable.
I think that would be confusing. Note that the existing class will continue to behave the same for pretty much any behavior, except some operations may raise DeprecationWarning.
Activity
JelleZijlstra commentedon Apr 24, 2026
Some more things:
builtins.sentinelwill raise TypeError on a non-stringname; we accept it. Let's also raise DeprecationWarning for this.nameargument tobuiltins.sentinelwill be positional only, but we currently accept it as a keyword arg. I think we can also DeprecationWarning this, though we'll have to complicate the signature a bit.builtins.sentinelhas__copy__returning itself, we don't.__setattr__maybe?).HexDecimal commentedon Apr 24, 2026
Renaming and deprecating a class name is difficult. I've made an attempt but I'm unsure if a perfect solution is possible.
When
__reduce__is used for singletons then copies will automatically reuse the objects identity. I've included tests for this.The parameter is
name: strwhich means we already don't accept non-strings even if they might pass at runtime. The purpose of type checking is to resolve these issues before they occur at runtime.JelleZijlstra commentedon Apr 25, 2026
We don't need to deprecate the class itself, just some particular behaviors. In the future we can indefinitely keep re-exporting builtins.sentinel as typing_extensions.Sentinel.
Thanks for working on this!
JelleZijlstra commentedon Apr 25, 2026
@HexDecimal argues on the PR (https://github.com/python/typing_extensions/pull/617/changes#r3141102069) that we should rename to
typing_extensions.sentinel:Curious what others think.
HexDecimal commentedon Apr 25, 2026
I can understand keeping
Sentinelavailable because people would've used it by this point and thus it has to stick around forever. Though I'd prefer if typeshed deprecated it in favor ofsentinel, linters will probably start doing that by themselves.What I really wonder is if anybody actually made weakrefs to it or added custom attributes. Otherwise I could've added a simple
__slots__to the implementation.JelleZijlstra commentedon Apr 25, 2026
typing-extensions is very widely used and backwards compatibility is important, so we generally have to assume that people have done all of those things.
For what it's worth, when I was implementing PEP-695 in Python, I initially made it so you could no longer assign custom attributes to TypeVar instances, and it broke some things. Similarly, we got bug reports when I accidentally made TypeVars (and I think also unions?) not weakrefable.
tmke8 commentedon Apr 30, 2026
What about keeping the old
Sentinelas it is (and deprecating it) and adding a newsentinelthat's as close as possible to the one in Python 3.15?JelleZijlstra commentedon May 1, 2026
I think that would be confusing. Note that the existing class will continue to behave the same for pretty much any behavior, except some operations may raise DeprecationWarning.
zedzhen commentedon May 19, 2026
PEP 661 is update (python/steering-council#258 (comment))