]> granicus.if.org Git - python/commitdiff
Issue #24373: Eliminate PEP 489 test refleaks
authorNick Coghlan <ncoghlan@gmail.com>
Thu, 4 Jun 2015 11:52:57 +0000 (21:52 +1000)
committerNick Coghlan <ncoghlan@gmail.com>
Thu, 4 Jun 2015 11:52:57 +0000 (21:52 +1000)
_testmultiphase and xxlimited now use tp_traverse and
tp_finalize to avoid reference leaks encountered when
combining tp_dealloc with PyType_FromSpec (see
issue #16690 for details)

Misc/NEWS
Modules/_testmultiphase.c
Modules/xxlimited.c

index 6367afd7fd5380cd7f5c98efdf5784432cde53be..5dea7f3605669fbe994c392559b2eb3252fbf2d9 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -29,6 +29,13 @@ Library
 
 - Issue #24369: Defend against key-changes during iteration.
 
+Tests
+-----
+
+- Issue #24373: _testmultiphase and xxlimited now use tp_traverse and
+  tp_finalize to avoid reference leaks encountered when combining tp_dealloc
+  with PyType_FromSpec (see issue #16690 for details)
+
 
 What's New in Python 3.5.0 beta 2?
 ==================================
index 7b98be2b8efe5b700ba4b79615481bd231ab80dd..2919687e112db74a42d15e256dada78be11b7f3a 100644 (file)
@@ -12,11 +12,18 @@ typedef struct {
 
 /* Example methods */
 
-static void
-Example_dealloc(ExampleObject *self)
+static int
+Example_traverse(ExampleObject *self, visitproc visit, void *arg)
 {
-    Py_XDECREF(self->x_attr);
-    PyObject_Del(self);
+    Py_VISIT(self->x_attr);
+    return 0;
+}
+
+static int
+Example_finalize(ExampleObject *self)
+{
+    Py_CLEAR(self->x_attr);
+    return 0;
 }
 
 static PyObject *
@@ -74,7 +81,8 @@ Example_setattr(ExampleObject *self, char *name, PyObject *v)
 
 static PyType_Slot Example_Type_slots[] = {
     {Py_tp_doc, "The Example type"},
-    {Py_tp_dealloc, Example_dealloc},
+    {Py_tp_finalize, Example_finalize},
+    {Py_tp_traverse, Example_traverse},
     {Py_tp_getattro, Example_getattro},
     {Py_tp_setattr, Example_setattr},
     {Py_tp_methods, Example_methods},
@@ -85,7 +93,7 @@ static PyType_Spec Example_Type_spec = {
     "_testimportexec.Example",
     sizeof(ExampleObject),
     0,
-    Py_TPFLAGS_DEFAULT,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,
     Example_Type_slots
 };
 
index 604456bffe674c560b71493a83e611a1a2fb033f..40c176063dbac4ea393ab2ba66b5aeb6eec20f47 100644 (file)
@@ -40,11 +40,18 @@ newXxoObject(PyObject *arg)
 
 /* Xxo methods */
 
-static void
-Xxo_dealloc(XxoObject *self)
+static int
+Xxo_traverse(XxoObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->x_attr);
+    return 0;
+}
+
+static int
+Xxo_finalize(XxoObject *self)
 {
-    Py_XDECREF(self->x_attr);
-    ((freefunc)PyType_GetSlot(Py_TYPE(self), Py_tp_free))(self);
+    Py_CLEAR(self->x_attr);
+    return 0;
 }
 
 static PyObject *
@@ -102,7 +109,8 @@ Xxo_setattr(XxoObject *self, char *name, PyObject *v)
 
 static PyType_Slot Xxo_Type_slots[] = {
     {Py_tp_doc, "The Xxo type"},
-    {Py_tp_dealloc, Xxo_dealloc},
+    {Py_tp_traverse, Xxo_traverse},
+    {Py_tp_finalize, Xxo_finalize},
     {Py_tp_getattro, Xxo_getattro},
     {Py_tp_setattr, Xxo_setattr},
     {Py_tp_methods, Xxo_methods},
@@ -113,7 +121,7 @@ static PyType_Spec Xxo_Type_spec = {
     "xxlimited.Xxo",
     sizeof(XxoObject),
     0,
-    Py_TPFLAGS_DEFAULT,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,
     Xxo_Type_slots
 };
 
@@ -247,6 +255,12 @@ xx_modexec(PyObject *m)
     Py_INCREF(ErrorObject);
     PyModule_AddObject(m, "error", ErrorObject);
 
+    /* Add Xxo */
+    o = PyType_FromSpec(&Xxo_Type_spec);
+    if (o == NULL)
+        goto fail;
+    PyModule_AddObject(m, "Xxo", o);
+
     /* Add Str */
     o = PyType_FromSpec(&Str_Type_spec);
     if (o == NULL)