Commit 77cbab3a authored by Stefan Behnel's avatar Stefan Behnel

merged fix for ticket #717 into master

parents 6bfb6480 847ef5d1
This diff is collapsed.
...@@ -3386,9 +3386,12 @@ class PyClassDefNode(ClassDefNode): ...@@ -3386,9 +3386,12 @@ class PyClassDefNode(ClassDefNode):
# find metaclass" dance at runtime # find metaclass" dance at runtime
self.metaclass = item.value self.metaclass = item.value
del keyword_args.key_value_pairs[i] del keyword_args.key_value_pairs[i]
if starstar_arg or (keyword_args and keyword_args.key_value_pairs): if starstar_arg:
self.mkw = ExprNodes.KeywordArgsNode( self.mkw = ExprNodes.KeywordArgsNode(
pos, keyword_args = keyword_args, starstar_arg = starstar_arg) pos, keyword_args = keyword_args and keyword_args.key_value_pairs or [],
starstar_arg = starstar_arg)
elif keyword_args and keyword_args.key_value_pairs:
self.mkw = keyword_args
else: else:
self.mkw = ExprNodes.NullNode(pos) self.mkw = ExprNodes.NullNode(pos)
if self.metaclass is None: if self.metaclass is None:
......
...@@ -1638,9 +1638,6 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform): ...@@ -1638,9 +1638,6 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
return node return node
if not isinstance(kwargs, ExprNodes.DictNode): if not isinstance(kwargs, ExprNodes.DictNode):
return node return node
if node.starstar_arg:
# we could optimize this by updating the kw dict instead
return node
return kwargs return kwargs
...@@ -1663,11 +1660,13 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform): ...@@ -1663,11 +1660,13 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
arg_tuple = node.positional_args arg_tuple = node.positional_args
if not isinstance(arg_tuple, ExprNodes.TupleNode): if not isinstance(arg_tuple, ExprNodes.TupleNode):
return node return node
if node.starstar_arg: keyword_args = node.keyword_args
if keyword_args and not isinstance(keyword_args, ExprNodes.DictNode):
# can't handle **kwargs
return node return node
args = arg_tuple.args args = arg_tuple.args
return self._dispatch_to_handler( return self._dispatch_to_handler(
node, function, args, node.keyword_args) node, function, args, keyword_args)
def visit_SimpleCallNode(self, node): def visit_SimpleCallNode(self, node):
self.visitchildren(node) self.visitchildren(node)
......
...@@ -440,7 +440,8 @@ def p_call_parse_args(s, allow_genexp = True): ...@@ -440,7 +440,8 @@ def p_call_parse_args(s, allow_genexp = True):
s.expect(')') s.expect(')')
return positional_args, keyword_args, star_arg, starstar_arg return positional_args, keyword_args, star_arg, starstar_arg
def p_call_build_packed_args(pos, positional_args, keyword_args, star_arg): def p_call_build_packed_args(pos, positional_args, keyword_args,
star_arg, starstar_arg=None):
arg_tuple = None arg_tuple = None
keyword_dict = None keyword_dict = None
if positional_args or not star_arg: if positional_args or not star_arg:
...@@ -454,11 +455,17 @@ def p_call_build_packed_args(pos, positional_args, keyword_args, star_arg): ...@@ -454,11 +455,17 @@ def p_call_build_packed_args(pos, positional_args, keyword_args, star_arg):
operand2 = star_arg_tuple) operand2 = star_arg_tuple)
else: else:
arg_tuple = star_arg_tuple arg_tuple = star_arg_tuple
if keyword_args: if keyword_args or starstar_arg:
keyword_args = [ExprNodes.DictItemNode(pos=key.pos, key=key, value=value) keyword_args = [ExprNodes.DictItemNode(pos=key.pos, key=key, value=value)
for key, value in keyword_args] for key, value in keyword_args]
keyword_dict = ExprNodes.DictNode(pos, if starstar_arg:
key_value_pairs = keyword_args) keyword_dict = ExprNodes.KeywordArgsNode(
pos,
starstar_arg = starstar_arg,
keyword_args = keyword_args)
else:
keyword_dict = ExprNodes.DictNode(
pos, key_value_pairs = keyword_args)
return arg_tuple, keyword_dict return arg_tuple, keyword_dict
def p_call(s, function): def p_call(s, function):
...@@ -474,12 +481,11 @@ def p_call(s, function): ...@@ -474,12 +481,11 @@ def p_call(s, function):
args = positional_args) args = positional_args)
else: else:
arg_tuple, keyword_dict = p_call_build_packed_args( arg_tuple, keyword_dict = p_call_build_packed_args(
pos, positional_args, keyword_args, star_arg) pos, positional_args, keyword_args, star_arg, starstar_arg)
return ExprNodes.GeneralCallNode(pos, return ExprNodes.GeneralCallNode(pos,
function = function, function = function,
positional_args = arg_tuple, positional_args = arg_tuple,
keyword_args = keyword_dict, keyword_args = keyword_dict)
starstar_arg = starstar_arg)
#lambdef: 'lambda' [varargslist] ':' test #lambdef: 'lambda' [varargslist] ':' test
......
...@@ -40,7 +40,7 @@ def call_non_dict_test(): ...@@ -40,7 +40,7 @@ def call_non_dict_test():
return func(**NonDict()) return func(**NonDict())
def call_non_dict_test_kw(): def call_non_dict_test_kw():
return func(a=5, **NonDict()) return func(b=5, **NonDict())
class SubDict(dict): class SubDict(dict):
...@@ -51,4 +51,4 @@ def call_sub_dict_test(): ...@@ -51,4 +51,4 @@ def call_sub_dict_test():
return func(**SubDict()) return func(**SubDict())
def call_sub_dict_test_kw(): def call_sub_dict_test_kw():
return func(a=5, **SubDict()) return func(b=5, **SubDict())
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