gh-151640: Track sharing of BytesIO buffer in free-threaded builds#151651
Conversation
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Additional context: This PR is intended to fix the specific While investigating the code path, I also found that The chosen fix is intentionally conservative: in free-threaded builds, avoid returning the internal I also considered fixing this lower in the resize/shared-buffer ownership path, but that seemed more invasive because it would require changing the interaction between |
b26fbb8 to
33bc6c8
Compare
|
I think always copying |
Keep zero-copy whole-buffer reads, but detach to a private buffer before a later write can mutate or resize an exposed BytesIO buffer.
33bc6c8 to
367b372
Compare
|
@nascheme Thanks for the prototype. I reworked the PR to follow the shared-buffer flag / copy-on-write approach, rather than always copying the buffer in free-threaded builds. The update includes the concurrent regression test and the NEWS entry. All CI checks are now green. Local validation also included free-threaded Py_DEBUG/refleak and the targeted free-threaded ThreadSanitizer regression: 10/10 passes with no diagnostics. The updated commit is 367b372. |
|
I'll let @ZeroIntensity take a look too but I think this can be merged. |
|
Thanks @pedramkarimii for the PR, and @ZeroIntensity for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14, 3.15. |
|
Sorry, @pedramkarimii and @ZeroIntensity, I could not cleanly backport this to |
|
Sorry, @pedramkarimii and @ZeroIntensity, I could not cleanly backport this to |
|
GH-153151 is a backport of this pull request to the 3.15 branch. |
|
GH-153153 is a backport of this pull request to the 3.14 branch. |
Fixesgh-151640.This replaces the earlier always-copy approach with the shared-buffer tracking / copy-on-write design proposed in review.
In free-threaded builds, whole-buffer read paths,
peek(), andgetvalue()can expose the internal bytes object. BytesIO marks that buffer as shared, and a later write detaches to a private buffer before mutating or resizing it. This preserves the zero-copy fast path when the buffer has not been exposed.The change includes:
getvalue()with buffer-resizing writes;BytesIO.__sizeof__expectation adjustment; andLocal validation:
test_ioandtest_free_threading.test_io;-R 3:3;make patchcheck.