mirror of https://github.com/python/cpython
Add garbage collection for module objects. Closes patch #102939 and
fixes bug #126345.
This commit is contained in:
parent
5a95e42841
commit
10e31cf82e
|
@ -18,6 +18,7 @@ PyModule_New(char *name)
|
|||
return NULL;
|
||||
nameobj = PyString_FromString(name);
|
||||
m->md_dict = PyDict_New();
|
||||
PyObject_GC_Init(m);
|
||||
if (m->md_dict == NULL || nameobj == NULL)
|
||||
goto fail;
|
||||
if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0)
|
||||
|
@ -130,11 +131,12 @@ _PyModule_Clear(PyObject *m)
|
|||
static void
|
||||
module_dealloc(PyModuleObject *m)
|
||||
{
|
||||
PyObject_GC_Fini(m);
|
||||
if (m->md_dict != NULL) {
|
||||
_PyModule_Clear((PyObject *)m);
|
||||
Py_DECREF(m->md_dict);
|
||||
}
|
||||
PyObject_DEL(m);
|
||||
PyObject_DEL(PyObject_AS_GC(m));
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
@ -211,11 +213,22 @@ module_setattr(PyModuleObject *m, char *name, PyObject *v)
|
|||
return PyDict_SetItemString(m->md_dict, name, v);
|
||||
}
|
||||
|
||||
/* We only need a traverse function, no clear function: If the module
|
||||
is in a cycle, md_dict will be cleared as well, which will break
|
||||
the cycle. */
|
||||
static int
|
||||
module_traverse(PyModuleObject *m, visitproc visit, void *arg)
|
||||
{
|
||||
if (m->md_dict != NULL)
|
||||
return visit(m->md_dict, arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyTypeObject PyModule_Type = {
|
||||
PyObject_HEAD_INIT(&PyType_Type)
|
||||
0, /*ob_size*/
|
||||
"module", /*tp_name*/
|
||||
sizeof(PyModuleObject), /*tp_size*/
|
||||
sizeof(PyModuleObject) + PyGC_HEAD_SIZE, /*tp_size*/
|
||||
0, /*tp_itemsize*/
|
||||
(destructor)module_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
|
@ -223,4 +236,16 @@ PyTypeObject PyModule_Type = {
|
|||
(setattrfunc)module_setattr, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
(reprfunc)module_repr, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
|
||||
0, /* tp_doc */
|
||||
(traverseproc)module_traverse, /* tp_traverse */
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue