bpo-1635741: Port gc module to multiphase initialization (GH-23377)
Signed-off-by: Christian Heimes <christian@python.org> Automerge-Triggered-By: GH:tiran
This commit is contained in:
parent
cfeb5437a8
commit
646d7fdefb
|
@ -0,0 +1 @@
|
|||
Port :mod:`gc` extension module to multiphase initialization (:pep:`489`)
|
|
@ -165,12 +165,17 @@ PyStatus
|
|||
_PyGC_Init(PyThreadState *tstate)
|
||||
{
|
||||
GCState *gcstate = &tstate->interp->gc;
|
||||
|
||||
gcstate->garbage = PyList_New(0);
|
||||
if (gcstate->garbage == NULL) {
|
||||
gcstate->garbage = PyList_New(0);
|
||||
if (gcstate->garbage == NULL) {
|
||||
return _PyStatus_NO_MEMORY();
|
||||
}
|
||||
return _PyStatus_NO_MEMORY();
|
||||
}
|
||||
|
||||
gcstate->callbacks = PyList_New(0);
|
||||
if (gcstate->callbacks == NULL) {
|
||||
return _PyStatus_NO_MEMORY();
|
||||
}
|
||||
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
|
@ -1992,59 +1997,50 @@ static PyMethodDef GcMethods[] = {
|
|||
{NULL, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static struct PyModuleDef gcmodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"gc", /* m_name */
|
||||
gc__doc__, /* m_doc */
|
||||
-1, /* m_size */
|
||||
GcMethods, /* m_methods */
|
||||
NULL, /* m_reload */
|
||||
NULL, /* m_traverse */
|
||||
NULL, /* m_clear */
|
||||
NULL /* m_free */
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_gc(void)
|
||||
static int
|
||||
gcmodule_exec(PyObject *module)
|
||||
{
|
||||
GCState *gcstate = get_gc_state();
|
||||
|
||||
PyObject *m = PyModule_Create(&gcmodule);
|
||||
|
||||
if (m == NULL) {
|
||||
return NULL;
|
||||
/* garbage and callbacks are initialized by _PyGC_Init() early in
|
||||
* interpreter lifecycle. */
|
||||
assert(gcstate->garbage != NULL);
|
||||
if (PyModule_AddObjectRef(module, "garbage", gcstate->garbage) < 0) {
|
||||
return -1;
|
||||
}
|
||||
assert(gcstate->callbacks != NULL);
|
||||
if (PyModule_AddObjectRef(module, "callbacks", gcstate->callbacks) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gcstate->garbage == NULL) {
|
||||
gcstate->garbage = PyList_New(0);
|
||||
if (gcstate->garbage == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
Py_INCREF(gcstate->garbage);
|
||||
if (PyModule_AddObject(m, "garbage", gcstate->garbage) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gcstate->callbacks == NULL) {
|
||||
gcstate->callbacks = PyList_New(0);
|
||||
if (gcstate->callbacks == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
Py_INCREF(gcstate->callbacks);
|
||||
if (PyModule_AddObject(m, "callbacks", gcstate->callbacks) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) { return NULL; }
|
||||
#define ADD_INT(NAME) if (PyModule_AddIntConstant(module, #NAME, NAME) < 0) { return -1; }
|
||||
ADD_INT(DEBUG_STATS);
|
||||
ADD_INT(DEBUG_COLLECTABLE);
|
||||
ADD_INT(DEBUG_UNCOLLECTABLE);
|
||||
ADD_INT(DEBUG_SAVEALL);
|
||||
ADD_INT(DEBUG_LEAK);
|
||||
#undef ADD_INT
|
||||
return m;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyModuleDef_Slot gcmodule_slots[] = {
|
||||
{Py_mod_exec, gcmodule_exec},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static struct PyModuleDef gcmodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
.m_name = "gc",
|
||||
.m_doc = gc__doc__,
|
||||
.m_size = 0, // per interpreter state, see: get_gc_state()
|
||||
.m_methods = GcMethods,
|
||||
.m_slots = gcmodule_slots
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_gc(void)
|
||||
{
|
||||
return PyModuleDef_Init(&gcmodule);
|
||||
}
|
||||
|
||||
/* Public API to invoke gc.collect() from C */
|
||||
|
|
Loading…
Reference in New Issue