diff options
author | Nick Coghlan <ncoghlan@gmail.com> | 2015-06-04 11:52:57 (GMT) |
---|---|---|
committer | Nick Coghlan <ncoghlan@gmail.com> | 2015-06-04 11:52:57 (GMT) |
commit | 53f95024d7ef25a39e70aa45ffdcefbb084821ed (patch) | |
tree | cbb1b3e934a59b2912ce172cc00bb467c56313c4 /Modules | |
parent | 4fabf02633f7f537a8318a7541eec02cb3338a0d (diff) | |
download | cpython-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')
-rw-r--r-- | Modules/_testmultiphase.c | 20 | ||||
-rw-r--r-- | Modules/xxlimited.c | 26 |
2 files changed, 34 insertions, 12 deletions
diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index 7b98be2..2919687 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -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 }; 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) |