diff --git a/mypy/typeops.py b/mypy/typeops.py index 48efe3532a1c0..8453da4dd31c0 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -37,6 +37,7 @@ from mypy.types import ( ELLIPSIS_TYPE_NAMES, NOT_IMPLEMENTED_TYPE_NAMES, + SENTINEL_TYPE_NAMES, AnyType, CallableType, ExtraAttrs, @@ -1056,6 +1057,7 @@ def is_singleton_identity_type(typ: ProperType) -> bool: (typ.type.is_enum and len(typ.type.enum_members) == 1) or (typ.type.fullname in ELLIPSIS_TYPE_NAMES) or (typ.type.fullname in NOT_IMPLEMENTED_TYPE_NAMES) + or (typ.type.fullname in SENTINEL_TYPE_NAMES) ) if isinstance(typ, LiteralType): return typ.is_enum_literal() or typ.is_sentinel_literal() or isinstance(typ.value, bool) diff --git a/test-data/unit/check-sentinels.test b/test-data/unit/check-sentinels.test index 6553979b99255..6d39c11375bb5 100644 --- a/test-data/unit/check-sentinels.test +++ b/test-data/unit/check-sentinels.test @@ -36,12 +36,22 @@ MISSING = Sentinel("MISSING") SPECIAL = Sentinel("SPECIAL") def func(x: int | MISSING | SPECIAL) -> None: - # We could reasonably do narrowing here, but currently we're pretty conservative - # about narrowing on ==. if x == MISSING: - assert_type(x, int | MISSING | SPECIAL) + assert_type(x, MISSING) + else: + assert_type(x, int | SPECIAL) +[builtins fixtures/ops.pyi] + +[case testSentinelNarrowingInSequence] +from typing_extensions import assert_type, Sentinel + +MISSING = Sentinel("MISSING") + +def func(var: str | MISSING | None) -> None: + if var in (MISSING, None): + assert_type(var, MISSING | None) else: - assert_type(x, int | MISSING | SPECIAL) + assert_type(var, str) [builtins fixtures/tuple.pyi] [case testSentinelSameReprDistinctTypes] diff --git a/test-data/unit/lib-stub/typing_extensions.pyi b/test-data/unit/lib-stub/typing_extensions.pyi index 6d614d8f1b915..47bae94a7f7d7 100644 --- a/test-data/unit/lib-stub/typing_extensions.pyi +++ b/test-data/unit/lib-stub/typing_extensions.pyi @@ -44,7 +44,6 @@ Never: _SpecialForm class Sentinel: def __init__(self, name: str, repr: str | None = None) -> None: ... - def __eq__(self, other: object) -> bool: ... sentinel = Sentinel TypeVarTuple: _SpecialForm