Skip to content

Commit ebd98bd

Browse files
committed
gh-153298: Fix data race in GenericAlias parameter initialization on FT
1 parent 1051384 commit ebd98bd

3 files changed

Lines changed: 47 additions & 1 deletion

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import unittest
2+
import types
3+
from typing import TypeVar
4+
from test.support import threading_helper
5+
6+
threading_helper.requires_working_threading(module=True)
7+
8+
9+
class TestGenericAlias(unittest.TestCase):
10+
def test_repr_race(self):
11+
# gh-153298
12+
13+
T = TypeVar('T')
14+
slot = [list[T]]
15+
16+
def access():
17+
for _ in range(2000):
18+
try:
19+
_ = slot[0].__parameters__
20+
except Exception:
21+
pass
22+
23+
def refresh():
24+
for _ in range(2000):
25+
slot[0] = list[T]
26+
27+
threading_helper.run_concurrently([
28+
*[access for _ in range(6)],
29+
*[refresh for _ in range(2)],
30+
])
31+
32+
33+
if __name__ == "__main__":
34+
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixes a data race in :class:`types.GenericAlias` ``__parameters__``
2+
initialization on free-threading builds.

Objects/genericaliasobject.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,7 @@ static PyMemberDef ga_members[] = {
841841
};
842842

843843
static PyObject *
844-
ga_parameters(PyObject *self, void *unused)
844+
ga_parameters_lock_held(PyObject *self)
845845
{
846846
gaobject *alias = (gaobject *)self;
847847
if (alias->parameters == NULL) {
@@ -853,6 +853,16 @@ ga_parameters(PyObject *self, void *unused)
853853
return Py_NewRef(alias->parameters);
854854
}
855855

856+
static PyObject *
857+
ga_parameters(PyObject *self, void *unused)
858+
{
859+
PyObject *result;
860+
Py_BEGIN_CRITICAL_SECTION(self);
861+
result = ga_parameters_lock_held(self);
862+
Py_END_CRITICAL_SECTION();
863+
return result;
864+
}
865+
856866
static PyObject *
857867
ga_unpacked_tuple_args(PyObject *self, void *unused)
858868
{

0 commit comments

Comments
 (0)