Skip to content

Commit 2996c91

Browse files
authored
Preserve literals when joining Literal and Instance with matching last_known_value (#19279)
Discovered in #19225.
1 parent 6c3c4a7 commit 2996c91

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

mypy/join.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,8 @@ def visit_literal_type(self, t: LiteralType) -> ProperType:
625625
if self.s.fallback.type.is_enum and t.fallback.type.is_enum:
626626
return mypy.typeops.make_simplified_union([self.s, t])
627627
return join_types(self.s.fallback, t.fallback)
628+
elif isinstance(self.s, Instance) and self.s.last_known_value == t:
629+
return t
628630
else:
629631
return join_types(self.s, t.fallback)
630632

test-data/unit/check-literal.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2976,3 +2976,22 @@ x: Type[Literal[1]] # E: Type[...] can't contain "Literal[...]"
29762976
y: Type[Union[Literal[1], Literal[2]]] # E: Type[...] can't contain "Union[Literal[...], Literal[...]]"
29772977
z: Type[Literal[1, 2]] # E: Type[...] can't contain "Union[Literal[...], Literal[...]]"
29782978
[builtins fixtures/tuple.pyi]
2979+
2980+
[case testJoinLiteralAndInstance]
2981+
from typing import Generic, TypeVar, Literal
2982+
2983+
T = TypeVar("T")
2984+
2985+
class A(Generic[T]): ...
2986+
2987+
def f(a: A[T], t: T) -> T: ...
2988+
def g(a: T, t: A[T]) -> T: ...
2989+
2990+
def check(obj: A[Literal[1]]) -> None:
2991+
reveal_type(f(obj, 1)) # N: Revealed type is "Literal[1]"
2992+
reveal_type(f(obj, '')) # E: Cannot infer type argument 1 of "f" \
2993+
# N: Revealed type is "Any"
2994+
reveal_type(g(1, obj)) # N: Revealed type is "Literal[1]"
2995+
reveal_type(g('', obj)) # E: Cannot infer type argument 1 of "g" \
2996+
# N: Revealed type is "Any"
2997+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)