Skip to content

Commit 646d7fd

Browse files
authored
bpo-1635741: Port gc module to multiphase initialization (GH-23377)
Signed-off-by: Christian Heimes <christian@python.org> Automerge-Triggered-By: GH:tiran
1 parent cfeb543 commit 646d7fd

File tree

2 files changed

+42
-45
lines changed

2 files changed

+42
-45
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Port :mod:`gc` extension module to multiphase initialization (:pep:`489`)

Modules/gcmodule.c

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,17 @@ PyStatus
165165
_PyGC_Init(PyThreadState *tstate)
166166
{
167167
GCState *gcstate = &tstate->interp->gc;
168+
169+
gcstate->garbage = PyList_New(0);
168170
if (gcstate->garbage == NULL) {
169-
gcstate->garbage = PyList_New(0);
170-
if (gcstate->garbage == NULL) {
171-
return _PyStatus_NO_MEMORY();
172-
}
171+
return _PyStatus_NO_MEMORY();
172+
}
173+
174+
gcstate->callbacks = PyList_New(0);
175+
if (gcstate->callbacks == NULL) {
176+
return _PyStatus_NO_MEMORY();
173177
}
178+
174179
return _PyStatus_OK();
175180
}
176181

@@ -1992,59 +1997,50 @@ static PyMethodDef GcMethods[] = {
19921997
{NULL, NULL} /* Sentinel */
19931998
};
19941999

1995-
static struct PyModuleDef gcmodule = {
1996-
PyModuleDef_HEAD_INIT,
1997-
"gc", /* m_name */
1998-
gc__doc__, /* m_doc */
1999-
-1, /* m_size */
2000-
GcMethods, /* m_methods */
2001-
NULL, /* m_reload */
2002-
NULL, /* m_traverse */
2003-
NULL, /* m_clear */
2004-
NULL /* m_free */
2005-
};
2006-
2007-
PyMODINIT_FUNC
2008-
PyInit_gc(void)
2000+
static int
2001+
gcmodule_exec(PyObject *module)
20092002
{
20102003
GCState *gcstate = get_gc_state();
20112004

2012-
PyObject *m = PyModule_Create(&gcmodule);
2013-
2014-
if (m == NULL) {
2015-
return NULL;
2016-
}
2017-
2018-
if (gcstate->garbage == NULL) {
2019-
gcstate->garbage = PyList_New(0);
2020-
if (gcstate->garbage == NULL) {
2021-
return NULL;
2022-
}
2023-
}
2024-
Py_INCREF(gcstate->garbage);
2025-
if (PyModule_AddObject(m, "garbage", gcstate->garbage) < 0) {
2026-
return NULL;
2027-
}
2028-
2029-
if (gcstate->callbacks == NULL) {
2030-
gcstate->callbacks = PyList_New(0);
2031-
if (gcstate->callbacks == NULL) {
2032-
return NULL;
2033-
}
2005+
/* garbage and callbacks are initialized by _PyGC_Init() early in
2006+
* interpreter lifecycle. */
2007+
assert(gcstate->garbage != NULL);
2008+
if (PyModule_AddObjectRef(module, "garbage", gcstate->garbage) < 0) {
2009+
return -1;
20342010
}
2035-
Py_INCREF(gcstate->callbacks);
2036-
if (PyModule_AddObject(m, "callbacks", gcstate->callbacks) < 0) {
2037-
return NULL;
2011+
assert(gcstate->callbacks != NULL);
2012+
if (PyModule_AddObjectRef(module, "callbacks", gcstate->callbacks) < 0) {
2013+
return -1;
20382014
}
20392015

2040-
#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) { return NULL; }
2016+
#define ADD_INT(NAME) if (PyModule_AddIntConstant(module, #NAME, NAME) < 0) { return -1; }
20412017
ADD_INT(DEBUG_STATS);
20422018
ADD_INT(DEBUG_COLLECTABLE);
20432019
ADD_INT(DEBUG_UNCOLLECTABLE);
20442020
ADD_INT(DEBUG_SAVEALL);
20452021
ADD_INT(DEBUG_LEAK);
20462022
#undef ADD_INT
2047-
return m;
2023+
return 0;
2024+
}
2025+
2026+
static PyModuleDef_Slot gcmodule_slots[] = {
2027+
{Py_mod_exec, gcmodule_exec},
2028+
{0, NULL}
2029+
};
2030+
2031+
static struct PyModuleDef gcmodule = {
2032+
PyModuleDef_HEAD_INIT,
2033+
.m_name = "gc",
2034+
.m_doc = gc__doc__,
2035+
.m_size = 0, // per interpreter state, see: get_gc_state()
2036+
.m_methods = GcMethods,
2037+
.m_slots = gcmodule_slots
2038+
};
2039+
2040+
PyMODINIT_FUNC
2041+
PyInit_gc(void)
2042+
{
2043+
return PyModuleDef_Init(&gcmodule);
20482044
}
20492045

20502046
/* Public API to invoke gc.collect() from C */

0 commit comments

Comments
 (0)