From 4c3f56e44a64f881a9751d23955553e84b55e546 Mon Sep 17 00:00:00 2001 From: Jin Hong Date: Tue, 7 Jul 2026 11:24:33 +0000 Subject: [PATCH] version: support importing under sub-interpreters Python 3.12+ won't load single-phase C extensions inside a sub-interpreter. Convert _version to multi-phase init so it imports there, and declare it safe to run with a per-interpreter GIL. _version has no state, so this is a mechanical conversion. Since lz4/__init__ imports it, this is also what lets `import lz4` work in a sub-interpreter. No API change, and older Python versions are unaffected. --- lz4/_version.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/lz4/_version.c b/lz4/_version.c index af606ab..ac3e733 100644 --- a/lz4/_version.c +++ b/lz4/_version.c @@ -96,26 +96,39 @@ static PyMethodDef module_methods[] = { } }; +static int +_version_exec (PyObject *module) +{ + #ifdef Py_GIL_DISABLED + PyUnstable_Module_SetGIL (module, Py_MOD_GIL_NOT_USED); + #endif + + return 0; +} + +static PyModuleDef_Slot _version_slots[] = + { + {Py_mod_exec, _version_exec}, +#if PY_VERSION_HEX >= 0x030c0000 + /* No state and the LZ4 version calls are reentrant, so _version is safe in + isolated sub-interpreters with their own GIL. */ + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, +#endif + {0, NULL}, + }; + static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "_version", - NULL, - -1, - module_methods + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_version", + .m_doc = NULL, + .m_size = 0, + .m_methods = module_methods, + .m_slots = _version_slots, }; PyMODINIT_FUNC PyInit__version(void) { - PyObject *module = PyModule_Create (&moduledef); - - if (module == NULL) - return NULL; - - #ifdef Py_GIL_DISABLED - PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED); - #endif - - return module; + return PyModuleDef_Init (&moduledef); }