Skip to content

Commit 55ae793

Browse files
committed
Remove _PyModule_GetGCHooks; get the hooks directly via internal API
1 parent 4f3712f commit 55ae793

File tree

5 files changed

+47
-21
lines changed

5 files changed

+47
-21
lines changed

Include/moduleobject.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,6 @@ struct PyModuleDef_Slot {
9696

9797
#ifndef Py_LIMITED_API
9898
#define _Py_mod_LAST_SLOT 13
99-
PyAPI_FUNC(int) _PyModule_GetGCHooks(
100-
PyObject *, traverseproc*, inquiry*, freefunc*); // For testing
10199
#endif
102100

103101
#endif /* New in 3.5 */

Lib/test/test_capi/test_module.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ def test_gc(self):
8585
self.assertEqual(mod.__name__, 'testmod')
8686
self.assertEqual(mod.__doc__, None)
8787

88+
# Check that the requested hook functions (which module_from_slots_gc
89+
# stores as attributes) match what's in the module (as retrieved by
90+
# _testinternalcapi.module_get_gc_hooks)
91+
_testinternalcapi = import_helper.import_module('_testinternalcapi')
92+
traverse, clear, free = _testinternalcapi.module_get_gc_hooks(mod)
93+
self.assertEqual(traverse, mod.traverse)
94+
self.assertEqual(clear, mod.clear)
95+
self.assertEqual(free, mod.free)
96+
8897
def test_token(self):
8998
mod = _testcapi.module_from_slots_token(FakeSpec())
9099
self.assertIsInstance(mod, types.ModuleType)

Modules/_testcapi/module.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,18 @@ module_from_slots_gc(PyObject *self, PyObject *spec)
9999
traverseproc traverse;
100100
inquiry clear;
101101
freefunc free;
102-
if (_PyModule_GetGCHooks(mod, &traverse, &clear, &free) < 0) {
102+
if (PyModule_Add(mod, "traverse", PyLong_FromVoidPtr(&noop_traverse)) < 0) {
103+
Py_DECREF(mod);
104+
return NULL;
105+
}
106+
if (PyModule_Add(mod, "clear", PyLong_FromVoidPtr(&noop_clear)) < 0) {
107+
Py_DECREF(mod);
108+
return NULL;
109+
}
110+
if (PyModule_Add(mod, "free", PyLong_FromVoidPtr(&noop_free)) < 0) {
103111
Py_DECREF(mod);
104112
return NULL;
105113
}
106-
assert(traverse == &noop_traverse);
107-
assert(clear == &noop_clear);
108-
assert(free == &noop_free);
109114
return mod;
110115
}
111116

Modules/_testinternalcapi.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2418,6 +2418,34 @@ set_vectorcall_nop(PyObject *self, PyObject *func)
24182418
Py_RETURN_NONE;
24192419
}
24202420

2421+
static PyObject *
2422+
module_get_gc_hooks(PyObject *self, PyObject *arg)
2423+
{
2424+
PyModuleObject *mod = (PyModuleObject *)arg;
2425+
PyObject *traverse = NULL;
2426+
PyObject *clear = NULL;
2427+
PyObject *free = NULL;
2428+
PyObject *result = NULL;
2429+
traverse = PyLong_FromVoidPtr(mod->md_state_traverse);
2430+
if (!traverse) {
2431+
goto finally;
2432+
}
2433+
clear = PyLong_FromVoidPtr(mod->md_state_clear);
2434+
if (!clear) {
2435+
goto finally;
2436+
}
2437+
free = PyLong_FromVoidPtr(mod->md_state_free);
2438+
if (!free) {
2439+
goto finally;
2440+
}
2441+
result = PyTuple_FromArray((PyObject*[]){ traverse, clear, free }, 3);
2442+
finally:
2443+
Py_XDECREF(traverse);
2444+
Py_XDECREF(clear);
2445+
Py_XDECREF(free);
2446+
return result;
2447+
}
2448+
24212449
static PyMethodDef module_functions[] = {
24222450
{"get_configs", get_configs, METH_NOARGS},
24232451
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
@@ -2527,6 +2555,7 @@ static PyMethodDef module_functions[] = {
25272555
#endif
25282556
{"simple_pending_call", simple_pending_call, METH_O},
25292557
{"set_vectorcall_nop", set_vectorcall_nop, METH_O},
2558+
{"module_get_gc_hooks", module_get_gc_hooks, METH_O},
25302559
{NULL, NULL} /* sentinel */
25312560
};
25322561

Objects/moduleobject.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -828,21 +828,6 @@ PyModule_GetToken(PyObject *m, void **token_p)
828828
return 0;
829829
}
830830

831-
int
832-
_PyModule_GetGCHooks(PyObject *m, traverseproc *traverse,
833-
inquiry *clear, freefunc *free)
834-
{
835-
if (!PyModule_Check(m)) {
836-
PyErr_BadInternalCall();
837-
return -1;
838-
}
839-
PyModuleObject *mod = (PyModuleObject *)m;
840-
*traverse = mod->md_state_traverse;
841-
*clear = mod->md_state_clear;
842-
*free = mod->md_state_free;
843-
return 0;
844-
}
845-
846831
PyObject*
847832
PyModule_GetNameObject(PyObject *mod)
848833
{

0 commit comments

Comments
 (0)