Skip to content

gh-161271: Drop the read buffer in _pyio.BufferedRandom.truncate() - #161273

Open
tsayin4 wants to merge 1 commit into
python:mainfrom
tsayin4:fix-pyio-truncate-read-buffer
Open

tsayin4 wants to merge 1 commit into
python:mainfrom
tsayin4:fix-pyio-truncate-read-buffer

Conversation

@tsayin4

@tsayin4 tsayin4 commented Nov 3, 2026 •

Copy link
Copy Markdown

_io.BufferedRandom.truncate() rewinds the raw stream and resets the read buffer
before truncating (buffered_flush_and_rewind_unlocked() in
Modules/_io/bufferedio.c). _pyio does not, although the comment there already
says "Use seek to flush the read buffer", so a read after truncate() can return
data that is no longer in the file:

>>> import _pyio, os
>>> open("x", "wb").write(b"abcdef")
6
>>> f = _pyio.open("x", "r+b"); f.read(1); f.truncate(0); f.read(), os.path.getsize("x")
(b'bcdef', 0)

The one-line self.seek(self.tell()) keeps the logical position unchanged (as
truncate() must) while rewinding the raw stream and emptying the read buffer, which
is what _io does.

Tested: the reproducer and the new test were run against _io, against unpatched
_pyio and against patched _pyio on 3.13 (the touched code is byte-identical on
main), plus a 25-case differential battery over r+b/ab+/w+b and truncation
points 0/1/3/None comparing return value, tell(), following read() and the
resulting file size: 12 divergences from _io before, 0 after. I have not run the
full test_io suite locally (no local build yet), so CI is the check for that.

@python-cla-bot

python-cla-bot Bot commented Nov 3, 2026

Copy link
Copy Markdown

The following commit authors need to sign the Contributor License Agreement:

CLA not signed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant