Skip to content

Commit 93d7b65

Browse files
committed
Forbid Sentinel conversion to bool
Going with a strict implementation as early as possible. This restriction can always be relaxed at a later time. A truth test on a sentinel implies that the sentinel is mixed in with other types during the test. In nearly all cases this is incorrect and could result in unexpected behavior.
1 parent 232a38f commit 93d7b65

File tree

3 files changed

+13
-1
lines changed

3 files changed

+13
-1
lines changed

doc/index.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1044,9 +1044,12 @@ Sentinel objects
10441044
of the sentinel object. If not provided, *name* will be used.
10451045

10461046
All sentinels with the same *name* and *module_name* have the same identity.
1047-
Sentinel objects are tested using :py:ref:`is`.
10481047
Sentinel identity is preserved across :py:mod:`copy` and :py:mod:`pickle`.
10491048

1049+
Sentinel objects are tested using :py:ref:`is`.
1050+
Sentinels have no truthiness and attempting to convert a sentinel to
1051+
:py:class:`bool` will raise :py:exc:`TypeError`.
1052+
10501053
Example::
10511054

10521055
>>> from typing_extensions import Sentinel, assert_type

src/test_typing_extensions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9337,6 +9337,11 @@ def test_sentinel_picklable_anonymous(self):
93379337
):
93389338
self.assertIs(anonymous_sentinel, pickle.loads(pickle.dumps(anonymous_sentinel, protocol=proto)))
93399339

9340+
def test_sentinel_bool(self):
9341+
with self.assertRaisesRegex(
9342+
TypeError, rf"{self.SENTINEL!r} is not convertable to bool",
9343+
):
9344+
bool(self.SENTINEL)
93409345

93419346

93429347
if __name__ == '__main__':

src/typing_extensions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4247,6 +4247,10 @@ def __reduce__(self) -> str:
42474247
"""Reduce this sentinel to a singleton."""
42484248
return self._name # Module is set from __module__ attribute
42494249

4250+
def __bool__(self) -> Never:
4251+
"""Raise TypeError."""
4252+
raise TypeError(f"Sentinel {self!r} is not convertable to bool.")
4253+
42504254

42514255
# Aliases for items that are in typing in all supported versions.
42524256
# We use hasattr() checks so this library will continue to import on

0 commit comments

Comments
 (0)