Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion mypy/meet.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,12 @@ def narrow_declared_type(declared: Type, narrowed: Type) -> Type:
]
)
if is_enum_overlapping_union(declared, narrowed):
return original_narrowed
# Quick check before reaching `is_overlapping_types`. If it's enum/literal overlap,
# avoid full expansion and make it faster.
assert isinstance(narrowed, UnionType)
return make_simplified_union(
[narrow_declared_type(declared, x) for x in narrowed.relevant_items()]
)
elif not is_overlapping_types(declared, narrowed, prohibit_none_typevar_overlap=True):
if state.strict_optional:
return UninhabitedType()
Expand Down
30 changes: 30 additions & 0 deletions test-data/unit/check-typeguard.test
Original file line number Diff line number Diff line change
Expand Up @@ -803,3 +803,33 @@ def test() -> None:
return
reveal_type(x) # N: Revealed type is "builtins.list[__main__.C]"
[builtins fixtures/tuple.pyi]

[case testTypeGuardedTypeDoesNotLeak]
# https://github.com/python/mypy/issues/18895
from enum import Enum
from typing import Union
from typing_extensions import TypeGuard, Literal

class Model(str, Enum):
MODEL_A1 = 'model_a1'
MODEL_A2 = 'model_a2'
MODEL_B = 'model_b'

MODEL_A = Literal[Model.MODEL_A1, Model.MODEL_A2]
MODEL_B = Literal[Model.MODEL_B]

def is_model_a(model: str) -> TypeGuard[MODEL_A]:
return True

def is_model_b(model: str) -> TypeGuard[MODEL_B]:
return True

def process_model(model: Union[MODEL_A, MODEL_B]) -> int:
return 42

def handle(model: Model) -> int:
if is_model_a(model) or is_model_b(model):
# TODO: should start passing after #18896
return process_model(model) # E: Argument 1 to "process_model" has incompatible type "Model"; expected "Union[Literal[Model.MODEL_A1, Model.MODEL_A2], Literal[Model.MODEL_B]]"
return 0
[builtins fixtures/tuple.pyi]