diff options
-rw-r--r-- | astroid/bases.py | 2 | ||||
-rw-r--r-- | astroid/rebuilder.py | 4 | ||||
-rw-r--r-- | astroid/scoped_nodes.py | 4 | ||||
-rw-r--r-- | astroid/tests/unittest_inference.py | 13 | ||||
-rw-r--r-- | astroid/tests/unittest_scoped_nodes.py | 12 |
5 files changed, 32 insertions, 3 deletions
diff --git a/astroid/bases.py b/astroid/bases.py index a66dddbb..09e61d17 100644 --- a/astroid/bases.py +++ b/astroid/bases.py @@ -389,7 +389,7 @@ class BoundMethod(UnboundMethod): parent=caller) empty = node_classes.Pass() cls.postinit(bases=bases.elts, body=[empty], decorators=[], - newstyle=True, metaclass=mcs) + newstyle=True, metaclass=mcs, keywords=[]) cls.locals = cls_locals return cls diff --git a/astroid/rebuilder.py b/astroid/rebuilder.py index e903fff2..4b3506bf 100644 --- a/astroid/rebuilder.py +++ b/astroid/rebuilder.py @@ -326,7 +326,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/scoped_nodes.py b/astroid/scoped_nodes.py index abad18aa..46df423d 100644 --- a/astroid/scoped_nodes.py +++ b/astroid/scoped_nodes.py @@ -1095,6 +1095,7 @@ class ClassDef(mixins.FilterStmtsMixin, LocalsDictNodeNG, col_offset=None, parent=None): self.instance_attrs = {} self.locals = {} + self.keywords = [] self.bases = [] self.body = [] self.name = name @@ -1104,7 +1105,8 @@ class ClassDef(mixins.FilterStmtsMixin, LocalsDictNodeNG, parent.frame().set_local(name, self) # pylint: disable=redefined-outer-name - def postinit(self, bases, body, decorators, newstyle=None, metaclass=None): + def postinit(self, bases, body, decorators, newstyle=None, metaclass=None, keywords=None): + self.keywords = keywords self.bases = bases self.body = body self.decorators = decorators diff --git a/astroid/tests/unittest_inference.py b/astroid/tests/unittest_inference.py index c1b714ad..b0ad5c1c 100644 --- a/astroid/tests/unittest_inference.py +++ b/astroid/tests/unittest_inference.py @@ -3224,6 +3224,19 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): self.assertIsInstance(inferred, nodes.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 a20014ea..e6ccb86d 100644 --- a/astroid/tests/unittest_scoped_nodes.py +++ b/astroid/tests/unittest_scoped_nodes.py @@ -1676,6 +1676,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']) + if __name__ == '__main__': unittest.main() |