summaryrefslogtreecommitdiffstats
path: root/Modules/xxlimited.c
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2015-06-04 11:52:57 (GMT)
committerNick Coghlan <ncoghlan@gmail.com>2015-06-04 11:52:57 (GMT)
commit53f95024d7ef25a39e70aa45ffdcefbb084821ed (patch)
treecbb1b3e934a59b2912ce172cc00bb467c56313c4 /Modules/xxlimited.c
parent4fabf02633f7f537a8318a7541eec02cb3338a0d (diff)
downloadcpython-53f95024d7ef25a39e70aa45ffdcefbb084821ed.zip
cpython-53f95024d7ef25a39e70aa45ffdcefbb084821ed.tar.gz
cpython-53f95024d7ef25a39e70aa45ffdcefbb084821ed.tar.bz2
Issue #24373: Eliminate PEP 489 test refleaks
_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)
Diffstat (limited to 'Modules/xxlimited.c')
-rw-r--r--Modules/xxlimited.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c
index 604456b..40c1760 100644
--- a/Modules/xxlimited.c
+++ b/Modules/xxlimited.c
@@ -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)