Skip to content

gh-158213: Don't return a str subclass from PyUnicodeWriter_Finish() - #158214

Merged
vstinner merged 1 commit into
python:mainfrom
fedonman:fix-unicode-writer-str-subclass
Sep 28, 2026
Merged

vstinner merged 1 commit into
python:mainfrom
fedonman:fix-unicode-writer-str-subclass

Conversation

@fedonman

@fedonman fedonman commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

_PyUnicodeWriter_WriteStr() now takes the read-only shortcut only for exact str objects, so a str subclass is copied into a new buffer and PyUnicodeWriter_Finish() returns a str. This fixes io.StringIO after writing a str subclass.

$ ./python -m test test_io.test_memoryio test_capi.test_unicode -v | grep -E 'str_subclass|Total tests|Result'
test_write_str_subclass (test.test_io.test_memoryio.CStringIOTest.test_write_str_subclass) ... ok
test_str_subclass (test.test_capi.test_unicode.PyUnicodeWriterTest.test_str_subclass) ... ok
Total tests: run=279
Result: SUCCESS

No NEWS entry: this fixes code added in GH-157861, which has not been released yet.

…ish()

Since pythonGH-157861, every writer uses the read-only optimization of
_PyUnicodeWriter_WriteStr(), so the first write of a str subclass
instance into an empty writer kept that object as the buffer, and
PyUnicodeWriter_Finish() returned it.  io.StringIO.getvalue() then
returned the written object itself, and the next write re-read it
through its __str__() method, which changed the contents and could make
read() read past the end of the buffer.

Only use the read-only optimization for exact str objects.  A subclass
is copied into a new buffer, as before pythonGH-157861.
@vstinner
vstinner merged commit 7352b6a into python:main Sep 28, 2026
56 checks passed
@vstinner

Copy link
Copy Markdown
Member

Oh, thanks for the && PyUnicode_CheckExact(str) fix! I always forget about str subclasses.

Thanks also for added tests, they cover well the change so it LGTM. I merged your fix.

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.

3 participants