diff --git a/mypy/typeops.py b/mypy/typeops.py index 3a229f9201aa..00431f02fa5e 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -34,6 +34,7 @@ from mypy.state import state from mypy.types import ( ELLIPSIS_TYPE_NAMES, + NOT_IMPLEMENTED_TYPE_NAMES, AnyType, CallableType, ExtraAttrs, @@ -996,8 +997,10 @@ def is_singleton_identity_type(typ: ProperType) -> bool: if isinstance(typ, NoneType): return True if isinstance(typ, Instance): - return (typ.type.is_enum and len(typ.type.enum_members) == 1) or ( - typ.type.fullname in ELLIPSIS_TYPE_NAMES + return ( + (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) ) if isinstance(typ, LiteralType): return typ.is_enum_literal() or isinstance(typ.value, bool) diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index 237271558ac6..00e018e6aec1 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -2714,7 +2714,14 @@ reveal_type(t.foo) # N: Revealed type is "__main__.C" [builtins fixtures/property.pyi] [case testNarrowingNotImplemented] +# flags: --python-version 3.10 from __future__ import annotations +import types + +def foo(x: types.NotImplementedType | str): + if x is not NotImplemented: + reveal_type(x) # N: Revealed type is "builtins.str" + from typing_extensions import Self class X: diff --git a/test-data/unit/lib-stub/types.pyi b/test-data/unit/lib-stub/types.pyi index 3f713c31e417..6670b7cace0d 100644 --- a/test-data/unit/lib-stub/types.pyi +++ b/test-data/unit/lib-stub/types.pyi @@ -19,3 +19,5 @@ if sys.version_info >= (3, 10): class UnionType: def __or__(self, x) -> UnionType: ... + + class NotImplementedType: ...