-
-
Notifications
You must be signed in to change notification settings - Fork 34.1k
Open
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtopic-free-threadingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
In free-threaded mode, calling copy on collections.deque is not thread safe and can raise RuntimeError: deque mutated during iteration errors.
Example code:
import sys
import threading
from collections import deque
from copy import copy
print(f"Python {sys.version}")
print(f"GIL enabled: {sys._is_gil_enabled()}")
d = deque(range(100))
stop = threading.Event()
def mutate():
i = 0
while not stop.is_set():
d.append(i)
if len(d) > 200:
d.popleft()
i += 1
def copy_loop():
while not stop.is_set():
copy(d)
barrier = threading.Barrier(5)
def run(fn):
barrier.wait()
fn()
threads = [
threading.Thread(target=run, args=(f,), daemon=True)
for f in [mutate, mutate, copy_loop, copy_loop]
]
for t in threads:
t.start()
barrier.wait()
stop.wait(timeout=5)
stop.set()
for t in threads:
t.join(timeout=5)
print("Done")Running under free-threaded build:
❯ ./python /tmp/deque.py
Python 3.15.0a6+ free-threading build (heads/main:945bf8ce1bf, Feb 13 2026, 22:04:08) [GCC 11.4.0]
GIL enabled: False
Exception in thread Thread-4 (run):
Exception in thread Thread-3 (run):
Traceback (most recent call last):
Traceback (most recent call last):
File "cpython/Lib/threading.py", line 1075, in _bootstrap_inner
self._context.run(self.run)
~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "cpython/Lib/threading.py", line 1017, in run
self._target(*self._args, **self._kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/deque.py", line 32, in run
fn()
~~^^
File "/tmp/deque.py", line 24, in copy_loop
copy(d)
~~~~^^^
File "cpython/Lib/copy.py", line 82, in copy
return copier(x)
RuntimeError: deque mutated during iteration
File "cpython/Lib/threading.py", line 1075, in _bootstrap_inner
self._context.run(self.run)
~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "cpython/Lib/threading.py", line 1017, in run
self._target(*self._args, **self._kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/deque.py", line 32, in run
fn()
~~^^
File "/tmp/deque.py", line 24, in copy_loop
copy(d)
~~~~^^^
File "cpython/Lib/copy.py", line 82, in copy
return copier(x)
RuntimeError: deque mutated during iteration
DoneCPython versions tested on:
CPython main branch, 3.14
Operating systems tested on:
Linux
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtopic-free-threadingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error