Skip to content

Commit 274789c

Browse files
committed
Do not leak TypeGuardedType from narrow_declared_type with enums
1 parent e9fa89b commit 274789c

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

mypy/meet.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,12 @@ def narrow_declared_type(declared: Type, narrowed: Type) -> Type:
143143
]
144144
)
145145
if is_enum_overlapping_union(declared, narrowed):
146-
return original_narrowed
146+
# Quick check before reaching `is_overlapping_types`. If it's enum/literal overlap,
147+
# avoid full expansion and make it faster.
148+
assert isinstance(narrowed, UnionType)
149+
return make_simplified_union(
150+
[narrow_declared_type(declared, x) for x in narrowed.relevant_items()]
151+
)
147152
elif not is_overlapping_types(declared, narrowed, prohibit_none_typevar_overlap=True):
148153
if state.strict_optional:
149154
return UninhabitedType()

test-data/unit/check-typeguard.test

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,3 +803,32 @@ def test() -> None:
803803
return
804804
reveal_type(x) # N: Revealed type is "builtins.list[__main__.C]"
805805
[builtins fixtures/tuple.pyi]
806+
807+
[case testTypeGuardedTypeDoesNotLeak]
808+
# https://github.com/python/mypy/issues/18895
809+
from enum import Enum
810+
from typing import Union
811+
from typing_extensions import TypeGuard, Literal
812+
813+
class Model(str, Enum):
814+
MODEL_A1 = 'model_a1'
815+
MODEL_A2 = 'model_a2'
816+
MODEL_B = 'model_b'
817+
818+
MODEL_A = Literal[Model.MODEL_A1, Model.MODEL_A2]
819+
MODEL_B = Literal[Model.MODEL_B]
820+
821+
def is_model_a(model: str) -> TypeGuard[MODEL_A]:
822+
return True
823+
824+
def is_model_b(model: str) -> TypeGuard[MODEL_B]:
825+
return True
826+
827+
def process_model(model: Union[MODEL_A, MODEL_B]) -> int:
828+
return 42
829+
830+
def handle(model: Model) -> int:
831+
if is_model_a(model) or is_model_b(model):
832+
return process_model(model)
833+
return 0
834+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)