diff --git a/mypy/checker.py b/mypy/checker.py index 6e258689fb3a..760a137500f9 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1440,8 +1440,11 @@ def lvalue_type_from_base(self, expr_node: Var, if base_type: if not has_no_typevars(base_type): - # TODO: Handle TupleType, don't cast - instance = cast(Instance, self.scope.active_self_type()) + self_type = self.scope.active_self_type() + if isinstance(self_type, TupleType): + instance = self_type.fallback + else: + instance = self_type itype = map_instance_to_supertype(instance, base) base_type = expand_type_by_instance(base_type, itype) diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 81aa3f6957e6..7d313da71452 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -412,6 +412,12 @@ b = B._make(['']) # type: B [builtins fixtures/list.pyi] +[case testNamedTupleIncompatibleRedefinition] +from typing import NamedTuple +class Crash(NamedTuple): + count: int # E: Incompatible types in assignment (expression has type "int", base class "tuple" defined the type as Callable[[Tuple[Any, ...], Any], int]) +[builtins fixtures/tuple.pyi] + [case testNamedTupleInClassNamespace] # https://github.com/python/mypy/pull/2553#issuecomment-266474341 from typing import NamedTuple diff --git a/test-data/unit/fixtures/tuple.pyi b/test-data/unit/fixtures/tuple.pyi index 0e45a776504b..4e53d12f76e6 100644 --- a/test-data/unit/fixtures/tuple.pyi +++ b/test-data/unit/fixtures/tuple.pyi @@ -1,6 +1,6 @@ # Builtins stub used in tuple-related test cases. -from typing import Iterable, Iterator, TypeVar, Generic, Sequence +from typing import Iterable, Iterator, TypeVar, Generic, Sequence, Any Tco = TypeVar('Tco', covariant=True) @@ -13,6 +13,7 @@ class type: class tuple(Sequence[Tco], Generic[Tco]): def __iter__(self) -> Iterator[Tco]: pass def __getitem__(self, x: int) -> Tco: pass + def count(self, obj: Any) -> int: pass class function: pass # We need int and slice for indexing tuples.