Commit 5d5e3576 authored by Stefan Behnel's avatar Stefan Behnel

partial cleanup of last commit

--HG--
extra : transplant_source : %DF%9C%95%AE%9B7m%05%AA%02%C9%9C%80L%88O0%CD%40c
parent c40dd27a
...@@ -5300,25 +5300,26 @@ class DictMergeNode(ExprNode): ...@@ -5300,25 +5300,26 @@ class DictMergeNode(ExprNode):
gil_message = "Constructing Python dict" gil_message = "Constructing Python dict"
def generate_evaluation_code(self, code): def generate_evaluation_code(self, code):
# Custom method used here because key-value
# pairs are evaluated and used one at a time.
code.mark_pos(self.pos) code.mark_pos(self.pos)
self.allocate_temp_result(code) self.allocate_temp_result(code)
if self.base_dict_node.type is Builtin.dict_type: self.base_dict_node.generate_evaluation_code(code)
code.putln( if self.base_dict_node.type is not Builtin.dict_type:
"%s = PyDict_Copy(%s); %s" % (
self.result(),
self.base_dict_node.py_result(),
code.error_goto_if_null(self.result(), self.pos)))
else:
# CPython supports calling functions with non-dicts, so do we # CPython supports calling functions with non-dicts, so do we
code.putln('if (likely(PyDict_Check(%s))) {' % code.putln('if (likely(PyDict_Check(%s))) {' %
self.base_dict_node.py_result()) self.base_dict_node.py_result())
if self.key_value_pairs:
code.putln( code.putln(
"%s = PyDict_Copy(%s); %s" % ( "%s = PyDict_Copy(%s); %s" % (
self.result(), self.result(),
self.base_dict_node.py_result(), self.base_dict_node.py_result(),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result())
else:
code.putln("%s = %s;" % (
self.result(),
self.base_dict_node.py_result()))
code.put_incref(self.result(), py_object_type)
if self.base_dict_node.type is not Builtin.dict_type:
code.putln('} else {') code.putln('} else {')
code.putln( code.putln(
"%s = PyObject_CallFunctionObjArgs(" "%s = PyObject_CallFunctionObjArgs("
...@@ -5326,17 +5327,22 @@ class DictMergeNode(ExprNode): ...@@ -5326,17 +5327,22 @@ class DictMergeNode(ExprNode):
self.result(), self.result(),
self.base_dict_node.py_result(), self.base_dict_node.py_result(),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result())
code.putln('}') code.putln('}')
self.base_dict_node.generate_disposal_code(code)
self.base_dict_node.free_temps(code)
code.put_gotref(self.py_result()) if self.key_value_pairs:
code.globalstate.use_utility_code(Nodes.raise_double_keywords_utility_code)
for item in self.key_value_pairs: for item in self.key_value_pairs:
item.generate_evaluation_code(code) item.generate_evaluation_code(code)
code.putln("if (PyDict_GetItem(%s, %s)) {" % ( code.putln("if (unlikely(PyDict_GetItem(%s, %s))) {" % (
self.result(), self.result(),
item.key.py_result())) item.key.py_result()))
code.putln('PyErr_SetString(PyExc_TypeError, ' # FIXME: find out function name at runtime!
'"got multiple values for keyword argument"); %s' % ( code.putln('__Pyx_RaiseDoubleKeywordsError("function", %s); %s' % (
code.error_goto(self.pos))) item.key.py_result(),
code.error_goto(self.pos)))
code.putln("}") code.putln("}")
code.put_error_if_neg(self.pos, code.put_error_if_neg(self.pos,
"PyDict_SetItem(%s, %s, %s)" % ( "PyDict_SetItem(%s, %s, %s)" % (
...@@ -5351,6 +5357,7 @@ class DictMergeNode(ExprNode): ...@@ -5351,6 +5357,7 @@ class DictMergeNode(ExprNode):
for item in self.key_value_pairs: for item in self.key_value_pairs:
item.annotate(code) item.annotate(code)
class ModuleNameMixin(object): class ModuleNameMixin(object):
def set_mod_name(self, env): def set_mod_name(self, env):
self.module_name = env.global_scope().qualified_name self.module_name = env.global_scope().qualified_name
......
...@@ -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,8 +440,8 @@ def p_call_parse_args(s, allow_genexp = True): ...@@ -440,8 +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( def p_call_build_packed_args(pos, positional_args, keyword_args,
pos, positional_args, keyword_args, star_arg, starstar_arg=None): 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:
...@@ -455,14 +455,14 @@ def p_call_build_packed_args( ...@@ -455,14 +455,14 @@ def p_call_build_packed_args(
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]
if starstar_arg: if starstar_arg:
keyword_dict = ExprNodes.DictMergeNode( keyword_dict = ExprNodes.DictMergeNode(
pos, pos,
key_value_pairs = keyword_args, base_dict_node = starstar_arg,
base_dict_node = starstar_arg) key_value_pairs = keyword_args)
else: else:
keyword_dict = ExprNodes.DictNode( keyword_dict = ExprNodes.DictNode(
pos, key_value_pairs = keyword_args) pos, key_value_pairs = keyword_args)
...@@ -485,8 +485,7 @@ def p_call(s, function): ...@@ -485,8 +485,7 @@ def p_call(s, function):
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
......
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