Skip to content

Commit 4c484ab

Browse files
committed
Add additional tests for STORE_ATTR.
1 parent 29ef0af commit 4c484ab

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

Lib/test/test_free_threading/test_races.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import threading
55
import time
66
import unittest
7+
import _testinternalcapi
78

89
from test.support import threading_helper
910

@@ -235,6 +236,40 @@ def mutate():
235236

236237
do_race(read, mutate)
237238

239+
def make_shared_key_dict(self):
240+
class C:
241+
pass
242+
243+
a = C()
244+
a.x = 1
245+
return a.__dict__
246+
247+
def test_racing_store_attr_dict(self):
248+
"""Test STORE_ATTR with various dictionary types."""
249+
class C:
250+
pass
251+
252+
c = C()
253+
254+
def set_value():
255+
for i in range(20):
256+
c.x = i
257+
258+
def mutate():
259+
nonlocal c
260+
c.x = 1
261+
self.assertTrue(_testinternalcapi.has_inline_values(c))
262+
for i in range(30):
263+
setattr(c, f"_{i}", None)
264+
self.assertFalse(_testinternalcapi.has_inline_values(c.__dict__))
265+
c.__dict__ = self.make_shared_key_dict()
266+
self.assertTrue(_testinternalcapi.has_split_table(c.__dict__))
267+
c.__dict__[1] = None
268+
self.assertFalse(_testinternalcapi.has_split_table(c.__dict__))
269+
c = C()
270+
271+
do_race(set_value, mutate)
272+
238273

239274
if __name__ == "__main__":
240275
unittest.main()

Modules/_testinternalcapi.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,6 +1989,14 @@ has_inline_values(PyObject *self, PyObject *obj)
19891989
Py_RETURN_FALSE;
19901990
}
19911991

1992+
static PyObject *
1993+
has_split_table(PyObject *self, PyObject *obj)
1994+
{
1995+
if (PyDict_Check(obj) && _PyDict_HasSplitTable((PyDictObject *)obj)) {
1996+
Py_RETURN_TRUE;
1997+
}
1998+
Py_RETURN_FALSE;
1999+
}
19922000

19932001
// Circumvents standard version assignment machinery - use with caution and only on
19942002
// short-lived heap types
@@ -2139,6 +2147,7 @@ static PyMethodDef module_functions[] = {
21392147
{"get_rare_event_counters", get_rare_event_counters, METH_NOARGS},
21402148
{"reset_rare_event_counters", reset_rare_event_counters, METH_NOARGS},
21412149
{"has_inline_values", has_inline_values, METH_O},
2150+
{"has_split_table", has_split_table, METH_O},
21422151
{"type_assign_specific_version_unsafe", type_assign_specific_version_unsafe, METH_VARARGS,
21432152
PyDoc_STR("forcefully assign type->tp_version_tag")},
21442153

0 commit comments

Comments
 (0)