From 5b13195253fc3f0376f1db466d8630410f19efee Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 4 May 2017 15:36:10 +0100 Subject: [PATCH] Remove use of join during semantic analysis MROs may not be populated yet, so the join may crash. See #3316 for additional context. Fixes #3315. --- mypy/semanal.py | 9 ++++++--- test-data/unit/check-namedtuple.test | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 729ed84bcc19..261e480383d8 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2048,9 +2048,12 @@ def build_namedtuple_typeinfo(self, name: str, items: List[str], types: List[Typ # Actual signature should return OrderedDict[str, Union[types]] ordereddictype = (self.named_type_or_none('builtins.dict', [strtype, AnyType()]) or self.object_type()) - # 'builtins.tuple' has only one type parameter, the corresponding type argument - # in the fallback instance is a join of all item types. - fallback = self.named_type('__builtins__.tuple', [join.join_type_list(types)]) + # 'builtins.tuple' has only one type parameter. + # + # TODO: The corresponding type argument in the fallback instance should be a join of + # all item types, but we can't do joins during this pass of semantic analysis + # and we are using Any as a workaround. + fallback = self.named_type('__builtins__.tuple', [AnyType()]) # Note: actual signature should accept an invariant version of Iterable[UnionType[types]]. # but it can't be expressed. 'new' and 'len' should be callable types. iterable_type = self.named_type_or_none('typing.Iterable', [AnyType()]) diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 51260733064a..87d2ce251b55 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -449,3 +449,13 @@ def f(x: a.X) -> None: [out] tmp/b.py:6: error: Revealed type is 'a.X' tmp/b.py:8: error: Revealed type is 'Tuple[Any, fallback=a.X]' + +[case testForwardReferenceInNamedTuple] +from typing import NamedTuple + +class A(NamedTuple): + b: 'B' + x: int + +class B: + pass