proj/portage:master commit in: src/
"Matt Turner" <[email protected]>
| Newsgroups | gmane.linux.gentoo.cvs |
|---|---|
| Message-ID | <1785963929.c4a1bd26b4ef28ba2595e0cd2180b7dcff21bf19.mattst88@gentoo> |
commit: c4a1bd26b4ef28ba2595e0cd2180b7dcff21bf19
Author: Matt Turner <mattst88 <AT> gentoo <DOT> org>
AuthorDate: Mon Aug 3 16:29:07 2026 +0000
Commit: Matt Turner <mattst88 <AT> gentoo <DOT> org>
CommitDate: Wed Aug 5 21:05:29 2026 +0000
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=c4a1bd26
dep: use multi-phase initialization for the _parser extension
Multi-phase init (PEP 489) has been available since Python 3.5 and is
the form the free-threading guide expects, so drop PyModule_Create() in
favor of PyModuleDef_Init() with a Py_mod_exec slot. The GIL declaration
moves from the PyUnstable_Module_SetGIL() call to a Py_mod_gil slot, and
a Py_mod_multiple_interpreters slot now states explicitly what was
already true: the interned strings and the Atom type are process-wide
statics, so the module supports only the main interpreter.
While here, replace the deprecated PyModule_AddObject() with
PyModule_AddType(), which handles the reference counting itself.
Signed-off-by: Matt Turner <mattst88 <AT> gentoo.org>
src/dep_atom.h | 7 +------
src/dep_parser.c | 54 +++++++++++++++++++++++++++++-------------------------
2 files changed, 30 insertions(+), 31 deletions(-)
diff --git a/src/dep_atom.h b/src/dep_atom.h
index 7451171c3..6e3cb66bd 100644
--- a/src/dep_atom.h
+++ b/src/dep_atom.h
@@ -143,12 +143,7 @@ static inline PyObject *atom_new(
/* Register AtomType with a module. Call after PyType_Ready. */
static inline int atom_add_to_module(PyObject *m)
{
- Py_INCREF(&AtomType);
- if (PyModule_AddObject(m, "Atom", (PyObject *)&AtomType) < 0) {
- Py_DECREF(&AtomType);
- return -1;
- }
- return 0;
+ return PyModule_AddType(m, &AtomType);
}
/* vim: set ts=4 sw=4 et: */
diff --git a/src/dep_parser.c b/src/dep_parser.c
index 191c4d56d..fbd3a0946 100644
--- a/src/dep_parser.c
+++ b/src/dep_parser.c
@@ -699,41 +699,45 @@ static PyMethodDef methods[] = {
{ NULL, NULL, 0, NULL },
};
+static int module_exec(PyObject *m)
+{
+ if (!init_globals())
+ return -1;
+
+ return atom_add_to_module(m);
+}
+
+static PyModuleDef_Slot slots[] = {
+ { Py_mod_exec, (void *)module_exec },
+#ifdef Py_mod_multiple_interpreters
+ /* The interned strings and the Atom type are process-wide statics, so the
+ * module must only ever be loaded into the main interpreter. */
+ { Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED },
+#endif
+#ifdef Py_mod_gil
+ /* Safe to run without the GIL: the character-class table and the interned
+ * strings are written once during module exec and only read afterwards,
+ * the scanner keeps all of its state on the stack or in a per-call
+ * context, and Atom is an ordinary refcounted object with no mutable
+ * fields. */
+ { Py_mod_gil, Py_MOD_GIL_NOT_USED },
+#endif
+ { 0, NULL },
+};
+
static struct PyModuleDef module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = MODULE_NAME,
.m_doc = NULL,
- .m_size = -1,
+ .m_size = 0,
.m_methods = methods,
+ .m_slots = slots,
};
PyMODINIT_FUNC
PyInit__parser(void)
{
- if (!init_globals())
- return NULL;
-
- PyObject *m = PyModule_Create(&module);
- if (!m)
- return NULL;
-
- if (atom_add_to_module(m) < 0) {
- Py_DECREF(m);
- return NULL;
- }
-
-#ifdef Py_GIL_DISABLED
- /* Safe to run without the GIL: the character-class table and the interned
- * strings are written once here and only read afterwards, the scanner
- * keeps all of its state on the stack or in a per-call context, and Atom
- * is an ordinary refcounted object with no mutable fields. */
- if (PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED) < 0) {
- Py_DECREF(m);
- return NULL;
- }
-#endif
-
- return m;
+ return PyModuleDef_Init(&module);
}
/* vim: set ts=4 sw=4 et: */