fix ticket #604: refcounting bugs in 'from ... import *'
authorStefan Behnel <scoder@users.berlios.de>
Sun, 28 Nov 2010 18:00:19 +0000 (19:00 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Sun, 28 Nov 2010 18:00:19 +0000 (19:00 +0100)
Cython/Compiler/ModuleNode.py
tests/run/import_star.pyx [new file with mode: 0644]

index b8f370f85711aa236578510001c990282b43d915..0cc0321051be10fd58b2c69ceaa10a3f0b14cadb 100644 (file)
@@ -1657,7 +1657,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                         code.putln("if (!(%s)) %s;" % (
                             entry.type.type_test_code("o"),
                             code.error_goto(entry.pos)))
-                    code.put_var_decref(entry)
+                    code.putln("Py_INCREF(o);")
+                    code.put_decref(entry.cname, entry.type, nanny=False)
                     code.putln("%s = %s;" % (
                         entry.cname, 
                         PyrexTypes.typecast(entry.type, py_object_type, "o")))
@@ -1670,7 +1671,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                         rhs,
                         entry.type.error_condition(entry.cname),
                         code.error_goto(entry.pos)))
-                    code.putln("Py_DECREF(o);")
                 else:
                     code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (name, entry.type))
                     code.putln(code.error_goto(entry.pos))
@@ -1679,12 +1679,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname)
         code.putln("}")
         code.putln("return 0;")
-        code.put_label(code.error_label)
-        # This helps locate the offending name.
-        code.putln('__Pyx_AddTraceback("%s");' % self.full_module_name);
+        if code.label_used(code.error_label):
+            code.put_label(code.error_label)
+            # This helps locate the offending name.
+            code.putln('__Pyx_AddTraceback("%s");' % self.full_module_name);
         code.error_label = old_error_label
         code.putln("bad:")
-        code.putln("Py_DECREF(o);")
         code.putln("return -1;")
         code.putln("}")
         code.putln(import_star_utility_code)
diff --git a/tests/run/import_star.pyx b/tests/run/import_star.pyx
new file mode 100644 (file)
index 0000000..c70b449
--- /dev/null
@@ -0,0 +1,29 @@
+
+cdef object executable, version_info
+cdef long hexversion
+
+from sys import *
+
+def test_cdefed_objects():
+    """
+    >>> ex, vi = test_cdefed_objects()
+    >>> assert ex is not None
+    >>> assert vi is not None
+    """
+    return executable, version_info
+
+def test_cdefed_cvalues():
+    """
+    >>> hexver = test_cdefed_cvalues()
+    >>> assert hexver is not None
+    >>> assert hexver > 0x02020000
+    """
+    return hexversion
+
+def test_non_cdefed_names():
+    """
+    >>> mod, pth = test_non_cdefed_names()
+    >>> assert mod is not None
+    >>> assert pth is not None
+    """
+    return modules, path