Cleanup type sharing.
authorRobert Bradshaw <robertwb@gmail.com>
Tue, 13 Aug 2013 05:21:45 +0000 (22:21 -0700)
committerRobert Bradshaw <robertwb@gmail.com>
Tue, 13 Aug 2013 05:21:45 +0000 (22:21 -0700)
Cython/Compiler/ModuleNode.py
Cython/Utility/CommonTypes.c

index db7266e..399f07a 100644 (file)
@@ -532,6 +532,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("    #error Cython requires Python 2.4+.")
         code.putln("#else")
         code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
+        
+        from Cython import __version__
+        code.putln('#define CYTHON_ABI "%s"' % __version__.replace('.', '_'))
 
         code.put(UtilityCode.load_as_string("CModulePreamble", "ModuleSetupCode.c")[1])
 
index e6bcca8..af10d39 100644 (file)
@@ -6,24 +6,43 @@ static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
 
 static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
     static PyObject* fake_module = NULL;
-    PyTypeObject* cached_type;
+    PyObject* sys = NULL;
+    PyObject* sys_modules = NULL;
+    PyObject* args = NULL;
+    PyTypeObject* cached_type = NULL;
+    char* cython_module = "_cython_" CYTHON_ABI;
     if (fake_module == NULL) {
-        PyObject* sys = PyImport_ImportModule("sys");
-        PyObject* sys_modules = PyObject_GetAttrString(sys, "modules");
-        fake_module = PyDict_GetItemString(sys_modules, "_cython");
-        if (fake_module == NULL) {
-            PyObject* args = PyTuple_New(1);
-            PyTuple_SET_ITEM(args, 0, __Pyx_PyStr_FromString("_cython"));
+        sys = PyImport_ImportModule("sys"); if (sys == NULL) goto bad;
+        sys_modules = PyObject_GetAttrString(sys, "modules"); if (sys_modules == NULL) goto bad;
+        fake_module = PyDict_GetItemString(sys_modules, cython_module);
+        if (fake_module != NULL) {
+            // borrowed
+            Py_INCREF(fake_module);
+        } else {
+            args = PyTuple_New(1); if (args == NULL) goto bad;
+            PyTuple_SET_ITEM(args, 0, __Pyx_PyStr_FromString(cython_module));
+            if (PyTuple_GET_ITEM(args, 0) == NULL) goto bad;
             fake_module = PyObject_Call((PyObject*) &PyModule_Type, args, NULL);
-            PyDict_SetItemString(sys_modules, "_cython", fake_module);
+            if (PyDict_SetItemString(sys_modules, cython_module, fake_module) < 0)
+                goto bad;
         }
     }
     if (PyObject_HasAttrString(fake_module, type->tp_name)) {
         cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name);
     } else {
-        PyType_Ready(type);
-        PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type);
+        if (PyType_Ready(type) < 0) goto bad;
+        if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0)
+            goto bad;
         cached_type = type;
     }
+
+cleanup:
+    Py_XDECREF(sys);
+    Py_XDECREF(sys_modules);
+    Py_XDECREF(args);
     return cached_type;
+
+bad:
+    cached_type = NULL;
+    goto cleanup;
 }