Skip to content

Commit 7484ac2

Browse files
committed
Fix crash when accessing named tuple class attribute
Fixes #979.
1 parent 57b2af3 commit 7484ac2

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

mypy/checkmember.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,19 @@ def analyze_member_access(name: str, typ: Type, node: Context, is_lvalue: bool,
8585
elif isinstance(typ, FunctionLike) and typ.is_type_obj():
8686
# Class attribute.
8787
# TODO super?
88-
itype = cast(Instance, typ.items()[0].ret_type)
89-
result = analyze_class_attribute_access(itype, name, node, is_lvalue, builtin_type, msg)
90-
if result:
91-
return result
92-
# Look up from the 'type' type.
93-
return analyze_member_access(name, typ.fallback, node, is_lvalue, is_super,
94-
builtin_type, msg, report_type=report_type)
88+
ret_type = typ.items()[0].ret_type
89+
if isinstance(ret_type, TupleType):
90+
ret_type = ret_type.fallback
91+
if isinstance(ret_type, Instance):
92+
result = analyze_class_attribute_access(ret_type, name, node, is_lvalue,
93+
builtin_type, msg)
94+
if result:
95+
return result
96+
# Look up from the 'type' type.
97+
return analyze_member_access(name, typ.fallback, node, is_lvalue, is_super,
98+
builtin_type, msg, report_type=report_type)
99+
else:
100+
assert False, 'Unexpected type {}'.format(repr(ret_type))
95101
elif isinstance(typ, FunctionLike):
96102
# Look up from the 'function' type.
97103
return analyze_member_access(name, typ.fallback, node, is_lvalue, is_super,

mypy/test/data/check-namedtuple.test

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,8 @@ l = [A(1)]
163163
a = (1,) # E: Incompatible types in assignment (expression has type "Tuple[int]", \
164164
variable has type "A")
165165
[builtins fixtures/list.py]
166+
167+
[case testNamedTupleMissingClassAttribute]
168+
import collections
169+
MyNamedTuple = collections.namedtuple('MyNamedTuple', ['spam', 'eggs'])
170+
MyNamedTuple.x # E: "MyNamedTuple" has no attribute "x"

0 commit comments

Comments
 (0)