Skip to content

gh-161275: Fix TextIOWrapper.truncate() with no argument - #161280

Open
tsayin4 wants to merge 1 commit into
python:mainfrom
tsayin4:fix-textio-truncate-position
Open

tsayin4 wants to merge 1 commit into
python:mainfrom
tsayin4:fix-textio-truncate-position

Conversation

@tsayin4

@tsayin4 tsayin4 commented Nov 4, 2026

Copy link
Copy Markdown

The buffer that a TextIOWrapper sits on top of reads ahead, so after a read its
position is not the position of the text stream. truncate() with no argument passed
nothing through to the buffer, so the stream was resized to the read-ahead position:

with open("f", "w") as f:
    f.write("abcde")

f = open("f", "r+")
f.read(2)
f.tell()        # 2
f.truncate()    # 5 -- the file is left untouched

With a file bigger than one chunk it truncates to 8192 instead. io.BufferedRandom
gets this right, and so does _pyio.TextIOWrapper, which passes tell() to the
buffer. The test added here fails on the C implementation and passes on the Python one
before the fix, so no _pyio change is needed -- this only brings _io into line.

Refs gh-161275.

🤖 Generated with Claude Code

@tsayin4
tsayin4 requested a review from cmaloney as a code owner November 4, 2026 00:04
@python-cla-bot

python-cla-bot Bot commented Nov 4, 2026

Copy link
Copy Markdown

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

CLA not signed

truncate() delegated to the buffer without an explicit position, so the stream
was resized to wherever the buffer had read ahead to rather than to the current
position of the text stream.  _pyio passes tell() through and already behaves
correctly, so this only changes the C implementation.
@tsayin4
tsayin4 force-pushed the fix-textio-truncate-position branch from b4be619 to 800bd26 Compare November 4, 2026 00:09
@cmaloney

cmaloney commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Please read and review the https://devguide.python.org/, in particular the parts around using AI and the lifecycle of a PR (https://devguide.python.org/getting-started/pull-request-lifecycle/). Don't force push to branches which are in Python PRs: https://devguide.python.org/getting-started/pull-request-lifecycle/#don-t-force-push

@tsayin4

tsayin4 commented Nov 4, 2026

Copy link
Copy Markdown
Author

That force push was mine and it won't happen again. I was fixing an unresolvable
:meth: target in the NEWS entry and amended the commit instead of adding one. I've read
the AI tools page and the PR lifecycle page now.

On disclosure: I use Claude Code, and it's noted at the bottom of the PR description. The
bug came out of diffing _io against _pyio behaviour; I reproduced it on 3.10, 3.11 and
3.13 and read the code on main before writing anything. truncate() hands pos straight
to the buffer, and after a read the buffer sits wherever its read-ahead ended, so on a
5 byte file read(2) then truncate() leaves the file at 5. _pyio passes tell()
through, which is why the test fails on _io and passes on _pyio untouched.

Happy to go through any of it. Also, if you'd rather I close the two _pyio PRs while
steering-council#372 is open, say so and I'll close them.

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.

2 participants