Skip to content

Commit 596a288

Browse files
authored
Narrowing for final type objects (#20661)
Fixes #20590 Fixes #15553 Closes #20627 Closes #15646
1 parent 61ffa65 commit 596a288

2 files changed

Lines changed: 45 additions & 0 deletions

File tree

mypy/typeops.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,10 @@ def is_singleton_identity_type(typ: ProperType) -> bool:
10041004
)
10051005
if isinstance(typ, LiteralType):
10061006
return typ.is_enum_literal() or isinstance(typ.value, bool)
1007+
if isinstance(typ, TypeType) and isinstance(typ.item, Instance) and typ.item.type.is_final:
1008+
return True
1009+
if isinstance(typ, CallableType) and typ.is_type_obj() and typ.type_object().is_final:
1010+
return True
10071011
return False
10081012

10091013

test-data/unit/check-python310.test

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3311,3 +3311,44 @@ def type_object(field_type: type[object]) -> str:
33113311
return "bar"
33123312
return ret
33133313
[builtins fixtures/dict.pyi]
3314+
3315+
3316+
[case testMatchFinalClass]
3317+
from typing import final, NoReturn
3318+
3319+
def assert_never(x: NoReturn) -> NoReturn: ...
3320+
3321+
class Types:
3322+
3323+
@final
3324+
class A:
3325+
pass
3326+
3327+
@final
3328+
class B:
3329+
pass
3330+
3331+
def foo(cls: type[Types.A | Types.B]) -> None:
3332+
match cls:
3333+
case Types.A:
3334+
reveal_type(cls) # N: Revealed type is "type[__main__.Types.A]"
3335+
case Types.B:
3336+
reveal_type(cls) # N: Revealed type is "type[__main__.Types.B]"
3337+
case _:
3338+
assert_never(cls)
3339+
3340+
3341+
class TypeTypes:
3342+
A: type[Types.A] = Types.A
3343+
B: type[Types.B] = Types.B
3344+
3345+
3346+
def bar(cls: type[Types.A | Types.B]) -> None:
3347+
match cls:
3348+
case TypeTypes.A:
3349+
reveal_type(cls) # N: Revealed type is "type[__main__.Types.A]"
3350+
case TypeTypes.B:
3351+
reveal_type(cls) # N: Revealed type is "type[__main__.Types.B]"
3352+
case _:
3353+
assert_never(cls)
3354+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)