Skip to content

Fix io.StringIO() checking initial_value before newline - #1268

Open
jseop-lim wants to merge 1 commit into
oracle:masterfrom
jseop-lim:fix/stringio-newline-order
Open

jseop-lim wants to merge 1 commit into
oracle:masterfrom
jseop-lim:fix/stringio-newline-order

Conversation

@jseop-lim

Copy link
Copy Markdown
Contributor

Description

Fixes #1257

io.StringIO() converted initial_value through an Argument Clinic TString conversion, which ran before newline was validated, so a call with both arguments invalid raised TypeError for initial_value instead of ValueError for newline. CPython's _io_StringIO___init___impl checks newline first and initial_value last (stringio.c#L670-L698).

AS-IS

>>> io.StringIO(b'', 'x')
TypeError: StringIO() argument must be str, not bytes
>>> io.StringIO(1, 'x')
TypeError: StringIO() argument must be str, not int

TO-BE

>>> io.StringIO(b'', 'x')
ValueError: illegal newline value: x
>>> io.StringIO(1, 'x')
ValueError: illegal newline value: x
>>> io.StringIO(b'')
TypeError: initial_value must be str or None, not bytes

(exception classes matching CPython; the newline message wording was already different on master)

Changes

  • Drop the clinic conversion of initial_value from StringIOBuiltins.InitNode and convert it with CastToTruffleStringNode after validateNewline, treating None and a missing argument as the empty string.
  • Add ErrorMessages.INITIAL_VALUE_MUST_BE_STR_OR_NONE_NOT_P for a non-str initial_value.
  • Add test_stringio_validates_newline_before_initial_value to tests/test_io.py.

Testing

mx python-jvm on darwin-aarch64, then mx graalpytest test_io.py (29 passed, 1 skipped). test.test_memoryio (161 passed) and test.test_univnewlines (34 passed) from lib-python pass. The new test fails on the unpatched build. Fourteen StringIO() argument combinations now raise the same exception classes as CPython 3.13.14.

The initial_value argument was converted by the argument clinic before
the body ran, so a non-str initial_value raised TypeError even when
newline was invalid. CPython checks newline first and raises
ValueError("illegal newline value: ...") in that case. Convert
initial_value after the newline check.

Signed-off-by: Jeongseop Lim <jeongseop_lim@korea.ac.kr>
@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Oct 31, 2026

This branch has not been deployed

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

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: io.StringIO() checks initial_value before newline, raising TypeError instead of ValueError

1 participant