diff options
-rw-r--r-- | astroid/tests/unittest_inference.py | 13 | ||||
-rw-r--r-- | astroid/tests/unittest_scoped_nodes.py | 12 | ||||
-rw-r--r-- | astroid/tree/rebuilder.py | 4 | ||||
-rw-r--r-- | astroid/tree/scoped_nodes.py | 7 |
4 files changed, 33 insertions, 3 deletions
diff --git a/astroid/tests/unittest_inference.py b/astroid/tests/unittest_inference.py index 9579850f..497b286c 100644 --- a/astroid/tests/unittest_inference.py +++ b/astroid/tests/unittest_inference.py @@ -3231,6 +3231,19 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): self.assertIsInstance(inferred, ClassDef) self.assertEqual(inferred.name, 'A') + @test_utils.require_version(minver='3.0') + def test_metaclass_with_keyword_args(self): + ast_node = extract_node(''' + class TestMetaKlass(type): + def __new__(mcs, name, bases, ns, kwo_arg): + return super().__new__(mcs, name, bases, ns) + + class TestKlass(metaclass=TestMetaKlass, kwo_arg=42): #@ + pass + ''') + inferred = next(ast_node.infer()) + self.assertIsInstance(inferred, nodes.ClassDef) + def test_delayed_attributes_without_slots(self): ast_node = extract_node(''' class A(object): diff --git a/astroid/tests/unittest_scoped_nodes.py b/astroid/tests/unittest_scoped_nodes.py index 0bdc2929..0eb2afad 100644 --- a/astroid/tests/unittest_scoped_nodes.py +++ b/astroid/tests/unittest_scoped_nodes.py @@ -1665,6 +1665,18 @@ class ClassNodeTest(ModuleLoader, unittest.TestCase): parent = bind.scope() self.assertEqual(len(parent.extra_decorators), 0) + @test_utils.require_version(minver='3.0') + def test_class_keywords(self): + data = ''' + class TestKlass(object, metaclass=TestMetaKlass, + foo=42, bar='baz'): + pass + ''' + astroid = builder.parse(data, __name__) + cls = astroid['TestKlass'] + self.assertEqual(len(cls.keywords), 2) + self.assertEqual([x.arg for x in cls.keywords], ['foo', 'bar']) + class CallSiteTest(unittest.TestCase): diff --git a/astroid/tree/rebuilder.py b/astroid/tree/rebuilder.py index c45467f8..7f518854 100644 --- a/astroid/tree/rebuilder.py +++ b/astroid/tree/rebuilder.py @@ -353,7 +353,9 @@ class TreeRebuilder(object): for child in node.bases], [self.visit(child, newnode) for child in node.body], - decorators, newstyle, metaclass) + decorators, newstyle, metaclass, + [self.visit(kwd, newnode) for kwd in node.keywords + if kwd.arg != 'metaclass'] if PY3 else []) return newnode def visit_const(self, node, parent): diff --git a/astroid/tree/scoped_nodes.py b/astroid/tree/scoped_nodes.py index e9c6a26d..257b13d9 100644 --- a/astroid/tree/scoped_nodes.py +++ b/astroid/tree/scoped_nodes.py @@ -1224,7 +1224,8 @@ class ClassDef(QualifiedNameMixin, base.FilterStmtsMixin, _newstyle = None def __init__(self, name=None, doc=None, lineno=None, - col_offset=None, parent=None): + col_offset=None, parent=None, keywords=None): + self.keywords = keywords self.bases = [] self.body = [] self.name = name @@ -1233,7 +1234,9 @@ class ClassDef(QualifiedNameMixin, base.FilterStmtsMixin, self.external_attrs = collections.defaultdict(list) super(ClassDef, self).__init__(lineno, col_offset, parent) - def postinit(self, bases, body, decorators, newstyle=None, metaclass=None): + # pylint: disable=redefined-outer-name + def postinit(self, bases, body, decorators, newstyle=None, metaclass=None, keywords=None): + self.keywords = keywords self.bases = bases self.body = body self.decorators = decorators |