Commit 53f95024 authored by Nick Coghlan's avatar Nick Coghlan

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)
parent 4fabf026
...@@ -29,6 +29,13 @@ Library ...@@ -29,6 +29,13 @@ Library
- Issue #24369: Defend against key-changes during iteration. - 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? What's New in Python 3.5.0 beta 2?
================================== ==================================
......
...@@ -12,11 +12,18 @@ typedef struct { ...@@ -12,11 +12,18 @@ typedef struct {
/* Example methods */ /* Example methods */
static void static int
Example_dealloc(ExampleObject *self) Example_traverse(ExampleObject *self, visitproc visit, void *arg)
{ {
Py_XDECREF(self->x_attr); Py_VISIT(self->x_attr);
PyObject_Del(self); return 0;
}
static int
Example_finalize(ExampleObject *self)
{
Py_CLEAR(self->x_attr);
return 0;
} }
static PyObject * static PyObject *
...@@ -74,7 +81,8 @@ Example_setattr(ExampleObject *self, char *name, PyObject *v) ...@@ -74,7 +81,8 @@ Example_setattr(ExampleObject *self, char *name, PyObject *v)
static PyType_Slot Example_Type_slots[] = { static PyType_Slot Example_Type_slots[] = {
{Py_tp_doc, "The Example type"}, {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_getattro, Example_getattro},
{Py_tp_setattr, Example_setattr}, {Py_tp_setattr, Example_setattr},
{Py_tp_methods, Example_methods}, {Py_tp_methods, Example_methods},
...@@ -85,7 +93,7 @@ static PyType_Spec Example_Type_spec = { ...@@ -85,7 +93,7 @@ static PyType_Spec Example_Type_spec = {
"_testimportexec.Example", "_testimportexec.Example",
sizeof(ExampleObject), sizeof(ExampleObject),
0, 0,
Py_TPFLAGS_DEFAULT, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,
Example_Type_slots Example_Type_slots
}; };
......
...@@ -40,11 +40,18 @@ newXxoObject(PyObject *arg) ...@@ -40,11 +40,18 @@ newXxoObject(PyObject *arg)
/* Xxo methods */ /* Xxo methods */
static void static int
Xxo_dealloc(XxoObject *self) 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); Py_CLEAR(self->x_attr);
((freefunc)PyType_GetSlot(Py_TYPE(self), Py_tp_free))(self); return 0;
} }
static PyObject * static PyObject *
...@@ -102,7 +109,8 @@ Xxo_setattr(XxoObject *self, char *name, PyObject *v) ...@@ -102,7 +109,8 @@ Xxo_setattr(XxoObject *self, char *name, PyObject *v)
static PyType_Slot Xxo_Type_slots[] = { static PyType_Slot Xxo_Type_slots[] = {
{Py_tp_doc, "The Xxo type"}, {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_getattro, Xxo_getattro},
{Py_tp_setattr, Xxo_setattr}, {Py_tp_setattr, Xxo_setattr},
{Py_tp_methods, Xxo_methods}, {Py_tp_methods, Xxo_methods},
...@@ -113,7 +121,7 @@ static PyType_Spec Xxo_Type_spec = { ...@@ -113,7 +121,7 @@ static PyType_Spec Xxo_Type_spec = {
"xxlimited.Xxo", "xxlimited.Xxo",
sizeof(XxoObject), sizeof(XxoObject),
0, 0,
Py_TPFLAGS_DEFAULT, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,
Xxo_Type_slots Xxo_Type_slots
}; };
...@@ -247,6 +255,12 @@ xx_modexec(PyObject *m) ...@@ -247,6 +255,12 @@ xx_modexec(PyObject *m)
Py_INCREF(ErrorObject); Py_INCREF(ErrorObject);
PyModule_AddObject(m, "error", 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 */ /* Add Str */
o = PyType_FromSpec(&Str_Type_spec); o = PyType_FromSpec(&Str_Type_spec);
if (o == NULL) if (o == NULL)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment