From c1530c07c0f8105e48f2ee6e195adfe356438a78 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Mon, 5 Jan 2026 15:15:13 -0500 Subject: [PATCH 1/2] gh-129824: Fix data race in _PyBuiltins_AddExceptions with subinterpreters Initialize the PyExc_OSError aliases statically to avoid data races. --- Objects/exceptions.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 9a43057b383d29..3547dfcfca5d60 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -25,14 +25,6 @@ class BaseExceptionGroup "PyBaseExceptionGroupObject *" "&PyExc_BaseExceptionGro /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b7c45e78cff8edc3]*/ -/* Compatibility aliases */ -PyObject *PyExc_EnvironmentError = NULL; // borrowed ref -PyObject *PyExc_IOError = NULL; // borrowed ref -#ifdef MS_WINDOWS -PyObject *PyExc_WindowsError = NULL; // borrowed ref -#endif - - static struct _Py_exc_state* get_exc_state(void) { @@ -2528,6 +2520,13 @@ MiddlingExtendsException(PyExc_OSError, ProcessLookupError, OSError, MiddlingExtendsException(PyExc_OSError, TimeoutError, OSError, "Timeout expired."); +/* Compatibility aliases */ +PyObject *PyExc_EnvironmentError = (PyObject *)&_PyExc_OSError; // borrowed ref +PyObject *PyExc_IOError = (PyObject *)&_PyExc_OSError; // borrowed ref +#ifdef MS_WINDOWS +PyObject *PyExc_WindowsError = (PyObject *)&_PyExc_OSError; // borrowed ref +#endif + /* * EOFError extends Exception */ @@ -4599,23 +4598,20 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod) if (PyDict_SetItemString(mod_dict, "ExceptionGroup", PyExc_ExceptionGroup)) { return -1; } - -#define INIT_ALIAS(NAME, TYPE) \ - do { \ - PyExc_ ## NAME = PyExc_ ## TYPE; \ - if (PyDict_SetItemString(mod_dict, # NAME, PyExc_ ## TYPE)) { \ - return -1; \ - } \ - } while (0) - - INIT_ALIAS(EnvironmentError, OSError); - INIT_ALIAS(IOError, OSError); + if (PyDict_SetItemString(mod_dict, "EnvironmentError", PyExc_OSError)) { + return -1; + } + if (PyDict_SetItemString(mod_dict, "EnvironmentError", PyExc_OSError)) { + return -1; + } + if (PyDict_SetItemString(mod_dict, "IOError", PyExc_OSError)) { + return -1; + } #ifdef MS_WINDOWS - INIT_ALIAS(WindowsError, OSError); + if (PyDict_SetItemString(mod_dict, "WindowsError", PyExc_OSError)) { + return -1; + } #endif - -#undef INIT_ALIAS - return 0; } From 8b1a2f94e8e178bc7f1b65aff2299adccc3afe2f Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Mon, 5 Jan 2026 15:23:07 -0500 Subject: [PATCH 2/2] Remove redundant lines --- Objects/exceptions.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 3547dfcfca5d60..ca6f323ac11fbc 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -4601,9 +4601,6 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod) if (PyDict_SetItemString(mod_dict, "EnvironmentError", PyExc_OSError)) { return -1; } - if (PyDict_SetItemString(mod_dict, "EnvironmentError", PyExc_OSError)) { - return -1; - } if (PyDict_SetItemString(mod_dict, "IOError", PyExc_OSError)) { return -1; }