From f342be80c10981440297139ccb40521aaa25d801 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Wed, 31 Dec 2025 21:02:32 -0800 Subject: [PATCH] [testing] Avoid narrowing TypeType This relates to changes made in #20492 --- mypy/checker.py | 1 + test-data/unit/check-narrowing.test | 20 ++++++++++++++++++++ test-data/unit/fixtures/type.pyi | 1 + 3 files changed, 22 insertions(+) diff --git a/mypy/checker.py b/mypy/checker.py index 4fcb1a367047..3b78c10e9930 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -6568,6 +6568,7 @@ def comparison_type_narrowing_helper(self, node: ComparisonExpr) -> tuple[TypeMa isinstance(p_expr := get_proper_type(expr_type), CallableType) and p_expr.is_type_obj() ) + and not isinstance(p_expr, TypeType) ): h = literal_hash(expr) if h is not None: diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index 64dc288e927a..e66f4b2b6a2f 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -2920,3 +2920,23 @@ def f2(x: Any) -> None: return reveal_type(x) # N: Revealed type is "Any" [builtins fixtures/tuple.pyi] + +[case testNarrowTypeVarType] +from typing import TypeVar + +T = TypeVar("T") + +class A: ... + +def foo(X: type[T]) -> T: + if X == A: + return X() + raise + +# It could be nice to make these two test cases consistent, but it would be tricky +# The above case is much more common in real world code +def bar(X: type[T]) -> T: + if X == A: + return A() # E: Incompatible return value type (got "A", expected "T") + raise +[builtins fixtures/type.pyi] diff --git a/test-data/unit/fixtures/type.pyi b/test-data/unit/fixtures/type.pyi index 0d93b2e1fcd6..55d84c3b3360 100644 --- a/test-data/unit/fixtures/type.pyi +++ b/test-data/unit/fixtures/type.pyi @@ -10,6 +10,7 @@ S = TypeVar("S") class object: def __init__(self) -> None: pass def __str__(self) -> 'str': pass + def __eq__(self, value: object, /) -> bool: ... class list(Generic[T]): pass