summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--astroid/bases.py2
-rw-r--r--astroid/rebuilder.py4
-rw-r--r--astroid/scoped_nodes.py4
-rw-r--r--astroid/tests/unittest_inference.py13
-rw-r--r--astroid/tests/unittest_scoped_nodes.py12
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()