https://github.com/python/cpython/commit/341b86e095e59f849c80312ccdb5b70e00fa5216
commit: 341b86e095e59f849c80312ccdb5b70e00fa5216
branch: 3.13
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: vstinner <vstin...@python.org>
date: 2025-04-23T14:12:03Z
summary:

[3.13] gh-132713: Fix typing.Union[index] race condition (GH-132802) (#132839)

gh-132713: Fix typing.Union[index] race condition (GH-132802)

Add union_init_parameters() helper function. Use a critical section
to initialize the 'parameters' member.
(cherry picked from commit dc3e9638c22fc1fa807a88c32316ac2558a4b879)

Co-authored-by: Victor Stinner <vstin...@python.org>

files:
M Objects/unionobject.c

diff --git a/Objects/unionobject.c b/Objects/unionobject.c
index bf5605686f8df7..79103bc2ac2961 100644
--- a/Objects/unionobject.c
+++ b/Objects/unionobject.c
@@ -270,17 +270,29 @@ static PyMemberDef union_members[] = {
         {0}
 };
 
-static PyObject *
-union_getitem(PyObject *self, PyObject *item)
+// Populate __parameters__ if needed.
+static int
+union_init_parameters(unionobject *alias)
 {
-    unionobject *alias = (unionobject *)self;
-    // Populate __parameters__ if needed.
+    int result = 0;
+    Py_BEGIN_CRITICAL_SECTION(alias);
     if (alias->parameters == NULL) {
         alias->parameters = _Py_make_parameters(alias->args);
         if (alias->parameters == NULL) {
-            return NULL;
+            result = -1;
         }
     }
+    Py_END_CRITICAL_SECTION();
+    return result;
+}
+
+static PyObject *
+union_getitem(PyObject *self, PyObject *item)
+{
+    unionobject *alias = (unionobject *)self;
+    if (union_init_parameters(alias) < 0) {
+        return NULL;
+    }
 
     PyObject *newargs = _Py_subs_parameters(self, alias->args, 
alias->parameters, item);
     if (newargs == NULL) {
@@ -314,11 +326,8 @@ static PyObject *
 union_parameters(PyObject *self, void *Py_UNUSED(unused))
 {
     unionobject *alias = (unionobject *)self;
-    if (alias->parameters == NULL) {
-        alias->parameters = _Py_make_parameters(alias->args);
-        if (alias->parameters == NULL) {
-            return NULL;
-        }
+    if (union_init_parameters(alias) < 0) {
+        return NULL;
     }
     return Py_NewRef(alias->parameters);
 }

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to