Skip to content

Commit 67034c7

Browse files
committed
Convert multiarray to multi-phase init (PEP 489)
1 parent 0145d7c commit 67034c7

File tree

3 files changed

+76
-52
lines changed

3 files changed

+76
-52
lines changed

numpy/_core/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
except ImportError as exc:
2424
import sys
2525

26+
# Bypass for the module re-initialization opt-out
27+
if exc.msg == "cannot load module more than once per process":
28+
raise
29+
2630
# Basically always, the problem should be that the C module is wrong/missing...
2731
if (
2832
isinstance(exc, ModuleNotFoundError)

numpy/_core/src/multiarray/_multiarray_tests.c.src

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,41 +2413,56 @@ static PyMethodDef Multiarray_TestsMethods[] = {
24132413
};
24142414

24152415

2416-
static struct PyModuleDef moduledef = {
2417-
PyModuleDef_HEAD_INIT,
2418-
"_multiarray_tests",
2419-
NULL,
2420-
-1,
2421-
Multiarray_TestsMethods,
2422-
NULL,
2423-
NULL,
2424-
NULL,
2425-
NULL
2426-
};
2416+
static int module_loaded = 0;
24272417

2428-
PyMODINIT_FUNC PyInit__multiarray_tests(void)
2418+
static int
2419+
_multiarray_tests_exec(PyObject *m)
24292420
{
2430-
PyObject *m;
2421+
// https://docs.python.org/3/howto/isolating-extensions.html#opt-out-limiting-to-one-module-object-per-process
2422+
if (module_loaded) {
2423+
PyErr_SetString(PyExc_ImportError,
2424+
"cannot load module more than once per process");
2425+
return -1;
2426+
}
2427+
module_loaded = 1;
24312428

2432-
m = PyModule_Create(&moduledef);
2433-
if (m == NULL) {
2434-
return m;
2429+
if (PyArray_ImportNumPyAPI() < 0) {
2430+
return -1;
24352431
}
2436-
import_array();
24372432
if (init_argparse_mutex() < 0) {
2438-
return NULL;
2433+
return -1;
24392434
}
24402435
if (PyErr_Occurred()) {
24412436
PyErr_SetString(PyExc_RuntimeError,
24422437
"cannot load _multiarray_tests module.");
24432438
}
24442439

2445-
#if Py_GIL_DISABLED
2446-
// signal this module supports running with the GIL disabled
2447-
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
2440+
return 0;
2441+
}
2442+
2443+
static struct PyModuleDef_Slot _multiarray_tests_slots[] = {
2444+
{Py_mod_exec, _multiarray_tests_exec},
2445+
#if PY_VERSION_HEX >= 0x030c00f0 // Python 3.12+
2446+
{Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED},
2447+
#endif
2448+
#if PY_VERSION_HEX >= 0x030d00f0 // Python 3.13+
2449+
// signal that this module supports running without an active GIL
2450+
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
24482451
#endif
2452+
{0, NULL},
2453+
};
2454+
2455+
static struct PyModuleDef moduledef = {
2456+
.m_base = PyModuleDef_HEAD_INIT,
2457+
.m_name = "_multiarray_tests",
2458+
.m_size = 0,
2459+
.m_methods = Multiarray_TestsMethods,
2460+
.m_slots = _multiarray_tests_slots,
2461+
};
24492462

2450-
return m;
2463+
PyMODINIT_FUNC PyInit__multiarray_tests(void)
2464+
{
2465+
return PyModuleDef_Init(&moduledef);
24512466
}
24522467

24532468
NPY_NO_EXPORT int

numpy/_core/src/multiarray/multiarraymodule.c

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4773,28 +4773,19 @@ initialize_thread_unsafe_state(void) {
47734773
return 0;
47744774
}
47754775

4776-
static struct PyModuleDef moduledef = {
4777-
PyModuleDef_HEAD_INIT,
4778-
"_multiarray_umath",
4779-
NULL,
4780-
-1,
4781-
array_module_methods,
4782-
NULL,
4783-
NULL,
4784-
NULL,
4785-
NULL
4786-
};
4776+
static int module_loaded = 0;
47874777

4788-
/* Initialization function for the module */
4789-
PyMODINIT_FUNC PyInit__multiarray_umath(void) {
4790-
PyObject *m, *d, *s;
4791-
PyObject *c_api;
4778+
static int
4779+
_multiarray_umath_exec(PyObject *m) {
4780+
PyObject *d, *s, *c_api;
47924781

4793-
/* Create the module and add the functions */
4794-
m = PyModule_Create(&moduledef);
4795-
if (!m) {
4796-
return NULL;
4782+
// https://docs.python.org/3/howto/isolating-extensions.html#opt-out-limiting-to-one-module-object-per-process
4783+
if (module_loaded) {
4784+
PyErr_SetString(PyExc_ImportError,
4785+
"cannot load module more than once per process");
4786+
return -1;
47974787
}
4788+
module_loaded = 1;
47984789

47994790
/* Initialize CPU features */
48004791
if (npy_cpu_init() < 0) {
@@ -5135,18 +5126,32 @@ PyMODINIT_FUNC PyInit__multiarray_umath(void) {
51355126
goto err;
51365127
}
51375128

5138-
#if Py_GIL_DISABLED
5139-
// signal this module supports running with the GIL disabled
5140-
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
5129+
return 0;
5130+
5131+
err:
5132+
return -1;
5133+
}
5134+
5135+
static struct PyModuleDef_Slot _multiarray_umath_slots[] = {
5136+
{Py_mod_exec, _multiarray_umath_exec},
5137+
#if PY_VERSION_HEX >= 0x030c00f0 // Python 3.12+
5138+
{Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED},
5139+
#endif
5140+
#if PY_VERSION_HEX >= 0x030d00f0 // Python 3.13+
5141+
// signal that this module supports running without an active GIL
5142+
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
51415143
#endif
5144+
{0, NULL},
5145+
};
51425146

5143-
return m;
5147+
static struct PyModuleDef moduledef = {
5148+
.m_base = PyModuleDef_HEAD_INIT,
5149+
.m_name = "_multiarray_umath",
5150+
.m_size = 0,
5151+
.m_methods = array_module_methods,
5152+
.m_slots = _multiarray_umath_slots,
5153+
};
51445154

5145-
err:
5146-
if (!PyErr_Occurred()) {
5147-
PyErr_SetString(PyExc_RuntimeError,
5148-
"cannot load multiarray module.");
5149-
}
5150-
Py_DECREF(m);
5151-
return NULL;
5155+
PyMODINIT_FUNC PyInit__multiarray_umath(void) {
5156+
return PyModuleDef_Init(&moduledef);
51525157
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy