From 236316ee8c6c9865ef1297425f1818724786bdbe Mon Sep 17 00:00:00 2001 From: Ashley Whetter Date: Sun, 19 May 2019 16:00:54 -0700 Subject: [PATCH] Fixed being unable to access class attributes on a NamedTuple Close PyCQA/pylint#1628 --- ChangeLog | 4 ++++ astroid/brain/brain_namedtuple_enum.py | 9 +++++++++ astroid/tests/unittest_brain.py | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5b21c00b3..6a8e5091b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -55,6 +55,10 @@ Release Date: TBA Close #665 +* Fix being unable to access class attributes on a NamedTuple. + + Close PyCQA/pylint#1628 + What's New in astroid 2.2.0? ============================ diff --git a/astroid/brain/brain_namedtuple_enum.py b/astroid/brain/brain_namedtuple_enum.py index c50ef04ae..de240671f 100644 --- a/astroid/brain/brain_namedtuple_enum.py +++ b/astroid/brain/brain_namedtuple_enum.py @@ -381,6 +381,15 @@ def infer_typing_namedtuple_class(class_node, context=None): generated_class_node = next(infer_named_tuple(node, context)) for method in class_node.mymethods(): generated_class_node.locals[method.name] = [method] + + for assign in class_node.body: + if not isinstance(assign, nodes.Assign): + continue + + for target in assign.targets: + attr = target.name + generated_class_node.locals[attr] = class_node.locals[attr] + return iter((generated_class_node,)) diff --git a/astroid/tests/unittest_brain.py b/astroid/tests/unittest_brain.py index 0ac9f4d20..f75710fe8 100644 --- a/astroid/tests/unittest_brain.py +++ b/astroid/tests/unittest_brain.py @@ -1006,6 +1006,7 @@ def test_namedtuple_class_form(self): from typing import NamedTuple class Example(NamedTuple): + CLASS_ATTR = "class_attr" mything: int Example(mything=1) @@ -1014,6 +1015,11 @@ class Example(NamedTuple): inferred = next(result.infer()) self.assertIsInstance(inferred, astroid.Instance) + class_attr = inferred.getattr("CLASS_ATTR")[0] + self.assertIsInstance(class_attr, astroid.AssignName) + const = next(class_attr.infer()) + self.assertEqual(const.value, "class_attr") + def test_typing_types(self): ast_nodes = builder.extract_node( """