make generators use tp_finalize instead of tp_del for cleanup in Py3.4+
authorStefan Behnel <stefan_ml@behnel.de>
Fri, 9 Aug 2013 06:58:10 +0000 (08:58 +0200)
committerStefan Behnel <stefan_ml@behnel.de>
Fri, 9 Aug 2013 06:58:10 +0000 (08:58 +0200)
Cython/Utility/Generator.c
Cython/Utility/ModuleSetupCode.c

index 8893798..475e8c3 100644 (file)
@@ -460,16 +460,20 @@ static void __Pyx_Generator_dealloc(PyObject *self) {
     PyObject_GC_UnTrack(gen);
     if (gen->gi_weakreflist != NULL)
         PyObject_ClearWeakRefs(self);
-    PyObject_GC_Track(self);
 
     if (gen->resume_label > 0) {
         /* Generator is paused, so we need to close */
+        PyObject_GC_Track(self);
+#if PY_VERSION_HEX >= 0x030400a1
+        if (PyObject_CallFinalizerFromDealloc(self))
+#else
         Py_TYPE(gen)->tp_del(self);
         if (self->ob_refcnt > 0)
+#endif
             return;                     /* resurrected.  :( */
+        PyObject_GC_UnTrack(self);
     }
 
-    PyObject_GC_UnTrack(self);
     __Pyx_Generator_clear(self);
     PyObject_GC_Del(gen);
 }
@@ -482,9 +486,11 @@ static void __Pyx_Generator_del(PyObject *self) {
     if (gen->resume_label <= 0)
         return ;
 
+#if PY_VERSION_HEX < 0x030400a1
     /* Temporarily resurrect the object. */
     assert(self->ob_refcnt == 0);
     self->ob_refcnt = 1;
+#endif
 
     /* Save the current exception, if any. */
     __Pyx_ErrFetch(&error_type, &error_value, &error_traceback);
@@ -499,6 +505,7 @@ static void __Pyx_Generator_del(PyObject *self) {
     /* Restore the saved exception. */
     __Pyx_ErrRestore(error_type, error_value, error_traceback);
 
+#if PY_VERSION_HEX < 0x030400a1
     /* Undo the temporary resurrection; can't use DECREF here, it would
      * cause a recursive call.
      */
@@ -532,6 +539,7 @@ static void __Pyx_Generator_del(PyObject *self) {
     --Py_TYPE(self)->tp_frees;
     --Py_TYPE(self)->tp_allocs;
 #endif
+#endif
 }
 
 static PyMemberDef __pyx_Generator_memberlist[] = {
@@ -578,7 +586,7 @@ static PyTypeObject __pyx_GeneratorType_type = {
     0,                                  /*tp_getattro*/
     0,                                  /*tp_setattro*/
     0,                                  /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags*/
     0,                                  /*tp_doc*/
     (traverseproc) __Pyx_Generator_traverse,   /*tp_traverse*/
     0,                                  /*tp_clear*/
@@ -604,12 +612,16 @@ static PyTypeObject __pyx_GeneratorType_type = {
     0,                                  /*tp_cache*/
     0,                                  /*tp_subclasses*/
     0,                                  /*tp_weaklist*/
+#if PY_VERSION_HEX >= 0x030400a1
+    0,                                  /*tp_del*/
+#else
     __Pyx_Generator_del,                /*tp_del*/
+#endif
 #if PY_VERSION_HEX >= 0x02060000
     0,                                  /*tp_version_tag*/
 #endif
 #if PY_VERSION_HEX >= 0x030400a1
-    0,                                  /*tp_finalize*/
+    __Pyx_Generator_del,                /*tp_finalize*/
 #endif
 };
 
index c0c59f6..8065ab9 100644 (file)
   #define Py_TPFLAGS_HAVE_VERSION_TAG 0
 #endif
 
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+  #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+
 /* new Py3.3 unicode type (PEP 393) */
 #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
   #define CYTHON_PEP393_ENABLED 1