Skip to content

str.maketrans on a mutating dict is not thread-safe #145142

Description

@eendebakpt

Crash report

What happened?

A reproducer (in the format of Lib/tests/test_free_threading/xxx.py):

importunittestfromtest.supportimportthreading_helperthreading_helper.requires_working_threading(module=True)
classItertoolsThreading(unittest.TestCase):
@threading_helper.reap_threadsdeftest_maketrans(self):
number_of_iterations=10number_of_attempts=100for_inrange(number_of_iterations):
print(f'iteration {_}')
d= {2000: 'a'}
defwork_iterator(dct):
foridxinrange(number_of_attempts):
str.maketrans(dct)
idx=2000+idx# outside range of small intsdct[idx] =chr(idx%16)
dct.pop(idx, None)
threading_helper.run_concurrently(work_iterator, nthreads=10, args=[d])
if__name__=="__main__":
unittest.main()
print('done')

At first glance it seems that the iteration using PyDict_Next is not safe (but maybe there are more unsafe parts):

while (PyDict_Next(x, &i, &key, &value)) {

(found when reviewing #145129)

CPython versions tested on:

CPython main branch

Operating systems tested on:

Windows

Output from running 'python -VV' on the command line:

No response

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    easyinterpreter-core(Objects, Python, Grammar, and Parser dirs)topic-free-threadingtype-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions