changeset: 96508:265eeb60443a branch: 3.5 parent: 96506:0d8679858272 user: Nick Coghlan date: Thu Jun 04 21:52:57 2015 +1000 files: Misc/NEWS Modules/_testmultiphase.c Modules/xxlimited.c description: 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) diff -r 0d8679858272 -r 265eeb60443a Misc/NEWS --- a/Misc/NEWS Thu Jun 04 00:09:56 2015 -0600 +++ b/Misc/NEWS Thu Jun 04 21:52:57 2015 +1000 @@ -29,6 +29,13 @@ - 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? ================================== diff -r 0d8679858272 -r 265eeb60443a Modules/_testmultiphase.c --- a/Modules/_testmultiphase.c Thu Jun 04 00:09:56 2015 -0600 +++ b/Modules/_testmultiphase.c Thu Jun 04 21:52:57 2015 +1000 @@ -12,11 +12,18 @@ /* 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 @@ 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 @@ "_testimportexec.Example", sizeof(ExampleObject), 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, Example_Type_slots }; diff -r 0d8679858272 -r 265eeb60443a Modules/xxlimited.c --- a/Modules/xxlimited.c Thu Jun 04 00:09:56 2015 -0600 +++ b/Modules/xxlimited.c Thu Jun 04 21:52:57 2015 +1000 @@ -40,11 +40,18 @@ /* Xxo methods */ -static void -Xxo_dealloc(XxoObject *self) +static int +Xxo_traverse(XxoObject *self, visitproc visit, void *arg) { - Py_XDECREF(self->x_attr); - ((freefunc)PyType_GetSlot(Py_TYPE(self), Py_tp_free))(self); + Py_VISIT(self->x_attr); + return 0; +} + +static int +Xxo_finalize(XxoObject *self) +{ + Py_CLEAR(self->x_attr); + return 0; } static PyObject * @@ -102,7 +109,8 @@ 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 @@ "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 @@ 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)