diff --git a/mypy/checker.py b/mypy/checker.py index 64852cb724f4..386f2a31d3f1 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -8463,13 +8463,7 @@ def get_type_range_of_type(self, typ: Type) -> TypeRange | None: return TypeRange(item, is_upper_bound=True) if isinstance(typ, FunctionLike) and typ.is_type_obj(): # If a type is generic, `isinstance` can only narrow its variables to Any. - any_parameterized = fill_typevars_with_any(typ.type_object()) - # Tuples may have unattended type variables among their items - if isinstance(any_parameterized, TupleType): - erased_type = erase_typevars(any_parameterized) - else: - erased_type = any_parameterized - return TypeRange(erased_type, is_upper_bound=False) + return TypeRange(fill_typevars_with_any(typ.type_object()), is_upper_bound=False) if isinstance(typ, TypeType): # Type[A] means "any type that is a subtype of A" rather than "precisely type A" # we indicate this by setting is_upper_bound flag diff --git a/mypy/typevars.py b/mypy/typevars.py index e871973104a2..807ce8acb12c 100644 --- a/mypy/typevars.py +++ b/mypy/typevars.py @@ -70,7 +70,7 @@ def fill_typevars_with_any(typ: TypeInfo) -> Instance | TupleType: erased_tuple_type = erase_typevars(typ.tuple_type, {tv.id for tv in typ.defn.type_vars}) assert isinstance(erased_tuple_type, ProperType) if isinstance(erased_tuple_type, TupleType): - return typ.tuple_type.copy_modified(fallback=inst) + return erased_tuple_type.copy_modified(fallback=inst) return inst diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 1ed57c72fcd2..9573e66da4c7 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -875,7 +875,7 @@ def f(o: Base) -> None: [out] [case testNamedTupleNew] -from typing import NamedTuple +from typing import Generic, NamedTuple, TypeVar Base = NamedTuple('Base', [('param', int)]) @@ -885,6 +885,18 @@ class Child(Base): Base(param=10) Child(param=10) + +T = TypeVar("T") +class GenericBase(NamedTuple, Generic[T]): + value: T + +class GenericChild(GenericBase[T]): + def __new__(cls, value: int) -> GenericChild[int]: + raise BaseException + +class BadChild(GenericBase[T]): + def __new__(cls, value: int) -> GenericBase[int]: # E: Incompatible return type for "__new__" (returns "GenericBase[int]", but must return a subtype of "BadChild[Any]") + raise BaseException [builtins fixtures/tuple.pyi] [case testNamedTupleClassMethodWithGenericReturnValue]