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)
This commit is contained in:
parent
4fabf02633
commit
53f95024d7
|
@ -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?
|
||||
==================================
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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_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 @@ 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)
|
||||
|
|
Loading…
Reference in New Issue