fix special case in for-from loop with object loop variable by adding yet another...
authorStefan Behnel <stefan_ml@behnel.de>
Fri, 8 Mar 2013 20:49:01 +0000 (21:49 +0100)
committerStefan Behnel <stefan_ml@behnel.de>
Fri, 8 Mar 2013 20:49:01 +0000 (21:49 +0100)
Cython/Compiler/Nodes.py
tests/run/for_from_pyvar_loop_T601.pyx
tests/run/py_classbody.py

index 9ccba1e..06be08a 100644 (file)
@@ -5738,16 +5738,24 @@ class ForFromStatNode(LoopNode, StatNode):
                 target_node = ExprNodes.PyTempNode(self.target.pos, None)
                 target_node.allocate(code)
                 interned_cname = code.intern_identifier(self.target.entry.name)
-                code.globalstate.use_utility_code(
-                    UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
-                code.putln("%s = __Pyx_GetModuleGlobalName(%s); %s" % (
+                if self.target.entry.scope.is_module_scope:
+                    code.globalstate.use_utility_code(
+                        UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
+                    lookup_func = '__Pyx_GetModuleGlobalName(%s)'
+                else:
+                    code.globalstate.use_utility_code(
+                        UtilityCode.load_cached("GetNameInClass", "ObjectHandling.c"))
+                    lookup_func = '__Pyx_GetNameInClass(%s, %%s)' % (
+                        self.target.entry.scope.namespace_cname)
+                code.putln("%s = %s; %s" % (
                     target_node.result(),
-                    interned_cname,
+                    lookup_func % interned_cname,
                     code.error_goto_if_null(target_node.result(), self.target.pos)))
                 code.put_gotref(target_node.result())
             else:
                 target_node = self.target
-            from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
+            from_py_node = ExprNodes.CoerceFromPyTypeNode(
+                self.loopvar_node.type, target_node, self.target.entry.scope)
             from_py_node.temp_code = loopvar_name
             from_py_node.generate_result_code(code)
             if self.target.entry.is_pyglobal:
index 30fc2b7..581d822 100644 (file)
@@ -53,3 +53,23 @@ def for_in_ctypedef_ulong():
     cdef object j = 0
     for j in range(size()):
         print j
+
+
+class ForFromLoopInPyClass(object):
+    """
+    >>> ForFromLoopInPyClass.i    # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    AttributeError: ...ForLoopInPyClass... has no attribute ...i...
+    >>> ForFromLoopInPyClass.k
+    0
+    >>> ForFromLoopInPyClass.m
+    1
+    """
+    for i from 0 <= i < 1:
+        pass
+
+    for k from 0 <= k < 2:
+        pass
+
+    for m from 0 <= m < 3:
+        pass
index ec2da6f..cd8e950 100644 (file)
@@ -37,3 +37,23 @@ class TestCdefAttr(object):
     cdefval1 = cdefvar
     del cdefvar
     # cdefval2 = cdefvar       # FIXME: doesn't currently work ...
+
+
+class ForLoopInPyClass(object):
+    """
+    >>> ForLoopInPyClass.i    # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    AttributeError: ...ForLoopInPyClass... has no attribute ...i...
+    >>> ForLoopInPyClass.k
+    0
+    >>> ForLoopInPyClass.m
+    1
+    """
+    for i in range(0):
+        pass
+
+    for k in range(1):
+        pass
+
+    for m in range(2):
+        pass