Commit 60bf01b9 authored by Stefan Behnel's avatar Stefan Behnel

optimise Py3-style metaclass also when other keywords are provided

parent 96bf6bc8
...@@ -2959,22 +2959,27 @@ class PyClassDefNode(ClassDefNode): ...@@ -2959,22 +2959,27 @@ class PyClassDefNode(ClassDefNode):
self.py3_style_class = True self.py3_style_class = True
self.bases = bases self.bases = bases
self.metaclass = None self.metaclass = None
if keyword_args and not starstar_arg and len(keyword_args.key_value_pairs) == 1: if keyword_args and not starstar_arg:
item = keyword_args.key_value_pairs[0] for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
if item.key.value == 'metaclass': if item.key.value == 'metaclass':
# special case: we already know the metaclass and if self.metaclass is not None:
# it's the only kwarg, so we don't need to do the error(item.pos, "keyword argument 'metaclass' passed multiple times")
# "build kwargs, find metaclass" dance at runtime # special case: we already know the metaclass,
self.metaclass = item.value # so we don't need to do the "build kwargs,
self.mkw = ExprNodes.NullNode(pos) # find metaclass" dance at runtime
if self.metaclass is None: self.metaclass = item.value
del keyword_args.key_value_pairs[i]
if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
self.mkw = ExprNodes.KeywordArgsNode( self.mkw = ExprNodes.KeywordArgsNode(
pos, keyword_args = keyword_args, starstar_arg = starstar_arg) pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
else:
self.mkw = ExprNodes.NullNode(pos)
if self.metaclass is None:
self.metaclass = ExprNodes.PyClassMetaclassNode( self.metaclass = ExprNodes.PyClassMetaclassNode(
pos, mkw = self.mkw, bases = self.bases) pos, mkw = self.mkw, bases = self.bases)
self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name, self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
doc = doc_node, metaclass = self.metaclass, bases = self.bases, doc = doc_node, metaclass = self.metaclass, bases = self.bases,
mkw = self.mkw, ) mkw = self.mkw)
self.classobj = ExprNodes.Py3ClassNode(pos, name = name, self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
bases = self.bases, dict = self.dict, doc = doc_node, bases = self.bases, dict = self.dict, doc = doc_node,
metaclass = self.metaclass, mkw = self.mkw) metaclass = self.metaclass, mkw = self.mkw)
......
...@@ -66,7 +66,8 @@ class Py3Base(type): ...@@ -66,7 +66,8 @@ class Py3Base(type):
def __prepare__(*args, **kwargs): def __prepare__(*args, **kwargs):
return ODict() return ODict()
@cython.test_assert_path_exists("//PyClassMetaclassNode", "//Py3ClassNode") @cython.test_fail_if_path_exists("//PyClassMetaclassNode")
@cython.test_assert_path_exists("//Py3ClassNode")
class Py3Foo(object, metaclass=Py3Base, foo=123): class Py3Foo(object, metaclass=Py3Base, foo=123):
""" """
>>> obj = Py3Foo() >>> obj = Py3Foo()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment