From 681567afe7ee524a5fbebb85c0e402c35fa58ac3 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Mon, 31 Aug 2026 16:11:04 +0200 Subject: [PATCH] Avoid leaking module object on numpy C-API import failure import_array() and import_umath() are macros that expand to `return NULL;` on failure. When they were called after PyModule_Create(), a failing import would return directly out of PyInit__ufuncs without releasing the module object, leaking the strong reference created by PyModule_Create(). Move the imports before the module is created so there is no owned reference to leak when an import fails. Co-Authored-By: Claude Opus 4.8 (1M context) --- mkl_umath/src/ufuncsmodule.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mkl_umath/src/ufuncsmodule.c b/mkl_umath/src/ufuncsmodule.c index 50dd7790..7fc25435 100644 --- a/mkl_umath/src/ufuncsmodule.c +++ b/mkl_umath/src/ufuncsmodule.c @@ -40,6 +40,11 @@ PyMODINIT_FUNC PyInit__ufuncs(void) PyObject *m; PyObject *d; + /* import_array()/import_umath() expand to `return NULL;` on failure, so + * call them before creating the module object to avoid leaking it. */ + import_array(); + import_umath(); + m = PyModule_Create(&_ufuncs_module); if (m == NULL) return NULL; @@ -50,9 +55,6 @@ PyMODINIT_FUNC PyInit__ufuncs(void) return NULL; } - import_array(); - import_umath(); - if (InitOperators(d) < 0) { Py_XDECREF(d); Py_XDECREF(m);