| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
…list In the free-threaded build, bytes.join() and bytearray.join() read items from the list with borrowed references and without holding its lock, so another thread could replace and free an item before it was increfed. Run the join under Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST, as PyUnicode_Join() already does.
|
The macOS (free-threading) failure is unrelated to this change: the test run was stopped by a SIGINT that escaped test_idle's InterruptTest.test_interrupt_blocking_call. The same failure happened on #158828 and on the Windows NoGIL buildbot (reported in gh-74112), and it is fixed by #158914. |
Sorry, something went wrong.
…-join-exact-fast The fast path holds no reference to the items, so in the free-threaded build it relies on the sequence being locked by the caller. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
Nice work! The failing CI indeed seems unrelated. Can you merge with main to trigger the CI again?
Sorry, something went wrong.
|
@eendebakpt Thanks! Merged main. The Windows failure is the known test_sslproto flake (gh-158646). Could you re-run it? |
Sorry, something went wrong.
|
The added lock will add a little bit of overhead in the FT build, but we can easily gain it back in a followup PR (where we can make use of the fact that the iterator argument is locked). For str.join there is a similar lock (see cpython/Objects/unicodeobject.c Line 10439 in 37cc8dd |
Sorry, something went wrong.
|
Thanks! Happy to look into the follow-up once this lands. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Fixes #158803
In the free-threaded build, bytes.join(), bytearray.join() and PyBytes_Join() (which share Objects/stringlib/join.h) read items from a list with PySequence_Fast_GET_ITEM(), which returns a borrowed reference, without holding the list's lock. If another thread replaces an item in the meantime, the old item can be freed before join() takes its own reference to it.
str.join() had the same problem and was fixed in gh-119247, which added Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST. This change uses the same pattern: the existing body becomes bytes_join_lock_held(), and bytes_join() calls it inside the critical section, as PyUnicode_Join() does with _PyUnicode_JoinArray().
The critical section can be suspended while an item's __buffer__() runs, or while a large result is copied with the thread state detached. Every item is increfed while the lock is held, and the existing size check still raises RuntimeError if the list changes size, so both cases stay safe.
In the default build the macros expand to an empty block.
Verification