Bug report
Bug description:
The place that negative indices for lists are offset currently in the free-threaded build can cause data to be returned that never actually resided at that offset (negatively speaking) if the list is modified during the access (either before or after the modification). Is this an issue?
|
i += PyList_GET_SIZE(self); |
Reproducer (it will happen eventually):
import re
import threading
def ins1(b, l):
b.wait()
l.insert(0, 'potato')
def get_secret(b, l):
b.wait()
assert l[-1] != 'super secret password'
def check(funcs, *args):
barrier = threading.Barrier(len(funcs))
thrds = []
for func in funcs:
thrd = threading.Thread(target=func, args=(barrier, *args))
thrds.append(thrd)
thrd.start()
for thrd in thrds:
thrd.join()
if __name__ == "__main__":
while True:
check([ins1] + [get_secret] * 10, ['super secret password', 'tomato'])
Output:
$ ./python ../check.py
Exception in thread Thread-38474 (get_secret):
Traceback (most recent call last):
File "/home/tom/work/cpython/free/cp/Lib/threading.py", line 1054, in _bootstrap_inner
self.run()
~~~~~~~~^^
File "/home/tom/work/cpython/free/cp/Lib/threading.py", line 996, in run
self._target(*self._args, **self._kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/tom/work/cpython/free/cp/../check.py", line 11, in get_secret
assert l[-1] != 'super secret password'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError
CPython versions tested on:
3.14
Operating systems tested on:
Linux