From 4a9406737fd3b7fba346617aa4c10014eafc8556 Mon Sep 17 00:00:00 2001 From: STerliakov Date: Thu, 12 Jun 2025 02:25:31 +0200 Subject: [PATCH] Preserve literals when joining Literal and Instance with matching last_known_value --- mypy/join.py | 2 ++ test-data/unit/check-literal.test | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/mypy/join.py b/mypy/join.py index a012a633dfa3..099df02680f0 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -625,6 +625,8 @@ def visit_literal_type(self, t: LiteralType) -> ProperType: if self.s.fallback.type.is_enum and t.fallback.type.is_enum: return mypy.typeops.make_simplified_union([self.s, t]) return join_types(self.s.fallback, t.fallback) + elif isinstance(self.s, Instance) and self.s.last_known_value == t: + return t else: return join_types(self.s, t.fallback) diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test index d91b257b0096..f995332643af 100644 --- a/test-data/unit/check-literal.test +++ b/test-data/unit/check-literal.test @@ -2976,3 +2976,22 @@ x: Type[Literal[1]] # E: Type[...] can't contain "Literal[...]" y: Type[Union[Literal[1], Literal[2]]] # E: Type[...] can't contain "Union[Literal[...], Literal[...]]" z: Type[Literal[1, 2]] # E: Type[...] can't contain "Union[Literal[...], Literal[...]]" [builtins fixtures/tuple.pyi] + +[case testJoinLiteralAndInstance] +from typing import Generic, TypeVar, Literal + +T = TypeVar("T") + +class A(Generic[T]): ... + +def f(a: A[T], t: T) -> T: ... +def g(a: T, t: A[T]) -> T: ... + +def check(obj: A[Literal[1]]) -> None: + reveal_type(f(obj, 1)) # N: Revealed type is "Literal[1]" + reveal_type(f(obj, '')) # E: Cannot infer type argument 1 of "f" \ + # N: Revealed type is "Any" + reveal_type(g(1, obj)) # N: Revealed type is "Literal[1]" + reveal_type(g('', obj)) # E: Cannot infer type argument 1 of "g" \ + # N: Revealed type is "Any" +[builtins fixtures/tuple.pyi]