bpo-28254: Add a C-API for controlling the GC state (GH-25687)
Add new C-API functions to control the state of the garbage collector:
PyGC_Enable(), PyGC_Disable(), PyGC_IsEnabled(),
corresponding to the functions in the gc module.
Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index db62aea..26ebacb 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -144,6 +144,67 @@ test_sizeof_c_types(PyObject *self, PyObject *Py_UNUSED(ignored))
#endif
}
+static PyObject*
+test_gc_control(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ int orig_enabled = PyGC_IsEnabled();
+ const char* msg = "ok";
+ int old_state;
+
+ old_state = PyGC_Enable();
+ msg = "Enable(1)";
+ if (old_state != orig_enabled) {
+ goto failed;
+ }
+ msg = "IsEnabled(1)";
+ if (!PyGC_IsEnabled()) {
+ goto failed;
+ }
+
+ old_state = PyGC_Disable();
+ msg = "disable(2)";
+ if (!old_state) {
+ goto failed;
+ }
+ msg = "IsEnabled(2)";
+ if (PyGC_IsEnabled()) {
+ goto failed;
+ }
+
+ old_state = PyGC_Enable();
+ msg = "enable(3)";
+ if (old_state) {
+ goto failed;
+ }
+ msg = "IsEnabled(3)";
+ if (!PyGC_IsEnabled()) {
+ goto failed;
+ }
+
+ if (!orig_enabled) {
+ old_state = PyGC_Disable();
+ msg = "disable(4)";
+ if (old_state) {
+ goto failed;
+ }
+ msg = "IsEnabled(4)";
+ if (PyGC_IsEnabled()) {
+ goto failed;
+ }
+ }
+
+ Py_RETURN_NONE;
+
+failed:
+ /* Try to clean up if we can. */
+ if (orig_enabled) {
+ PyGC_Enable();
+ } else {
+ PyGC_Disable();
+ }
+ PyErr_Format(TestError, "GC control failed in %s", msg);
+ return NULL;
+}
static PyObject*
test_list_api(PyObject *self, PyObject *Py_UNUSED(ignored))
@@ -5544,6 +5605,7 @@ static PyMethodDef TestMethods[] = {
{"PyDateTime_DATE_GET", test_PyDateTime_DATE_GET, METH_O},
{"PyDateTime_TIME_GET", test_PyDateTime_TIME_GET, METH_O},
{"PyDateTime_DELTA_GET", test_PyDateTime_DELTA_GET, METH_O},
+ {"test_gc_control", test_gc_control, METH_NOARGS},
{"test_list_api", test_list_api, METH_NOARGS},
{"test_dict_iteration", test_dict_iteration, METH_NOARGS},
{"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS},