From: Robert Bradshaw Date: Thu, 9 Apr 2009 23:58:05 +0000 (-0700) Subject: Another for..from fix when target is a python global X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=f3d1391618b5b1ad879110316aff3c2d9e5d0aa8;p=cython.git Another for..from fix when target is a python global --- diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index a51027c6..e912d98e 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -4002,12 +4002,28 @@ class ForFromStatNode(LoopNode, StatNode): self.body.generate_execution_code(code) code.put_label(code.continue_label) if self.py_loopvar_node: - # Reassign py variable to loop var here. - # (For consistancy, should rarely come up in practice.) + # This mess is to make for..from loops with python targets behave + # exactly like those with C targets with regards to re-assignment + # of the loop variable. import ExprNodes - from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, self.target, None) + if self.target.entry.is_pyglobal: + # We know target is a NameNode, this is the only ugly case. + target_node = ExprNodes.PyTempNode(self.target.pos, None) + target_node.result_code = code.funcstate.allocate_temp(py_object_type, False) + code.putln("%s = __Pyx_GetName(%s, %s); %s" % ( + target_node.result_code, + Naming.module_cname, + self.target.entry.interned_cname, + code.error_goto_if_null(target_node.result_code, self.target.pos))) + code.put_gotref(target_node.result_code) + else: + target_node = self.target + from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None) from_py_node.temp_code = loopvar_name from_py_node.generate_result_code(code) + if self.target.entry.is_pyglobal: + code.put_decref_clear(target_node.result_code, py_object_type) + code.funcstate.release_temp(target_node.result_code) code.putln("}") if self.py_loopvar_node: # This is potentially wasteful, but we don't want the semantics to diff --git a/tests/run/range_optimisation_T203.pyx b/tests/run/range_optimisation_T203.pyx index eadfde12..00e94a97 100644 --- a/tests/run/range_optimisation_T203.pyx +++ b/tests/run/range_optimisation_T203.pyx @@ -46,6 +46,12 @@ at 1 at 3 at 7 15 +>>> for_from_py_global_target_reassignment(10, 2) +at 0 +at 1 +at 3 +at 7 +15 >>> for_in_target_reassignment(10, 2) at 0 at 1 @@ -112,6 +118,13 @@ def for_from_py_target_reassignment(int bound, int factor): i *= factor return i +def for_from_py_global_target_reassignment(int bound, int factor): + global g_var + for g_var from 0 <= g_var < bound: + print "at", g_var + g_var *= factor + return g_var + def for_in_target_reassignment(int bound, int factor): cdef int i = 100 for i in range(bound):