From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Wed, 8 Jul 2026 15:30:51 +0000 (+0200) Subject: [3.15] gh-153298: Fix data race in `GenericAlias` parameter initialization on FT... X-Git-Tag: v3.15.0b4~75 X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=288e3cedd1d5761b132eec9e72d952c3f2bf469b;p=thirdparty%2FPython%2Fcpython.git [3.15] gh-153298: Fix data race in `GenericAlias` parameter initialization on FT (GH-153318) (#153345) gh-153298: Fix data race in `GenericAlias` parameter initialization on FT (GH-153318) (cherry picked from commit 68abf17fa926db94dc17f01a7095bdcee2a52314) Co-authored-by: sobolevn --- diff --git a/Lib/test/test_free_threading/test_types.py b/Lib/test/test_free_threading/test_types.py new file mode 100644 index 000000000000..76fcf1590122 --- /dev/null +++ b/Lib/test/test_free_threading/test_types.py @@ -0,0 +1,33 @@ +import unittest +from typing import TypeVar +from test.support import threading_helper + +threading_helper.requires_working_threading(module=True) + + +class TestGenericAlias(unittest.TestCase): + def test_parameters_race(self): + # gh-153298 + + T = TypeVar('T') + slot = [list[T]] + + def access(): + for _ in range(2000): + try: + _ = slot[0].__parameters__ + except Exception: + pass + + def refresh(): + for _ in range(2000): + slot[0] = list[T] + + threading_helper.run_concurrently([ + *[access for _ in range(6)], + *[refresh for _ in range(2)], + ]) + + +if __name__ == "__main__": + unittest.main() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-08-13-23-11.gh-issue-153298.wvcXxN.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-08-13-23-11.gh-issue-153298.wvcXxN.rst new file mode 100644 index 000000000000..38d548834d5e --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-08-13-23-11.gh-issue-153298.wvcXxN.rst @@ -0,0 +1,2 @@ +Fixes a data race in :class:`types.GenericAlias` ``__parameters__`` +initialization on free-threading builds. diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index c2083e6fcb77..4e85927def7e 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -841,7 +841,7 @@ static PyMemberDef ga_members[] = { }; static PyObject * -ga_parameters(PyObject *self, void *unused) +ga_parameters_lock_held(PyObject *self) { gaobject *alias = (gaobject *)self; if (alias->parameters == NULL) { @@ -853,6 +853,16 @@ ga_parameters(PyObject *self, void *unused) return Py_NewRef(alias->parameters); } +static PyObject * +ga_parameters(PyObject *self, void *unused) +{ + PyObject *result; + Py_BEGIN_CRITICAL_SECTION(self); + result = ga_parameters_lock_held(self); + Py_END_CRITICAL_SECTION(); + return result; +} + static PyObject * ga_unpacked_tuple_args(PyObject *self, void *unused) {