Skip to content

Match CPython's str subscript TypeError message#1

Closed
kim-jaedeok wants to merge 1 commit into
mainfrom
str-subscript-typeerror-message
Closed

Match CPython's str subscript TypeError message#1
kim-jaedeok wants to merge 1 commit into
mainfrom
str-subscript-typeerror-message

Conversation

@kim-jaedeok

Copy link
Copy Markdown
Owner

Summary

Make str subscripting with a non-integer index raise the same TypeError
message as CPython, and drop the expectedFailure marker on
string_tests.test_subscript.

Before / after ('abc'['def']):

message
CPython 3.14 string indices must be integers, not 'str'
RustPython (before) str indices must be integers or slices or classes that override __index__ operator, not 'str'
RustPython (after) string indices must be integers, not 'str'

Only the error message differed — indexing itself (int / negative / slice)
already behaved correctly. CPython gives str its own wording in
unicode_subscript (see python/cpython#88276, fixed in 3.11), distinct from the
shared sequence message used by list/tuple/bytes.

Approach

  • Add SequenceIndex::try_from_borrowed_object_with_err, which keeps the shared
    index-parsing logic but lets the caller supply the TypeError raised for a
    non-index object.
  • try_from_borrowed_object now delegates to it with the existing wording, so
    every other sequence caller (list/tuple/bytes/bytearray/array/mmap/
    struct-sequence) is byte-for-byte unchanged.
  • str::_getitem — the single path shared by __getitem__ and the mapping
    subscript slot — supplies the CPython-accurate message.

Scoped intentionally to str only: CPython declined to unify the sequence
messages (python/cpython#75731, rejected), so the other types' wording is left
as-is.

Testing

  • test_str / test_userstring test_subscript now pass (marker removed).
  • Byte-for-byte match with CPython 3.14.6 for str/object/None/float
    indices, and for UserString as receiver.
  • list/tuple/bytes messages verified unchanged; rustpython-vm and
    rustpython-codegen unit tests pass.

🤖 Generated with Claude Code

`str.__getitem__` with a non-index key raised the shared sequence
wording ("str indices must be integers or slices or classes that
override __index__ operator, not 'x'") instead of CPython's
str-specific "string indices must be integers, not 'x'" (bpo-44110 /
gh-88276, Python 3.11).

Add `SequenceIndex::try_from_borrowed_object_with_err`, which takes a
caller-supplied error closure, and have the existing
`try_from_borrowed_object` delegate to it with the unchanged shared
message. `str._getitem` now supplies the CPython-accurate message,
which flows through both `__getitem__` and the mapping subscript slot.
Other sequence types keep the shared wording.

Removes the expectedFailure marker on
`string_tests.StringLikeTest.test_subscript`, fixing it for both
test_str and test_userstring.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 18, 2026 18:42

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns RustPython’s str subscripting TypeError wording with CPython by allowing str to supply a custom non-index error message while keeping the shared sequence index parsing logic unchanged for all other sequence types.

Changes:

  • Added SequenceIndex::try_from_borrowed_object_with_err to allow callers to customize the TypeError emitted for non-index objects.
  • Updated str subscripting (PyStr::_getitem) to emit CPython’s "string indices must be integers, not '...'" message.
  • Removed the @unittest.expectedFailure marker from Lib/test/string_tests.py::test_subscript now that the test passes.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
Lib/test/string_tests.py Removes expectedFailure for test_subscript now that the error message matches CPython.
crates/vm/src/sliceable.rs Introduces an alternate SequenceIndex constructor that accepts a caller-provided TypeError for non-index objects.
crates/vm/src/builtins/str.rs Uses the new constructor to produce CPython-accurate str subscript TypeError wording.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kim-jaedeok

Copy link
Copy Markdown
Owner Author

Superseded by the upstream PR: RustPython#8319

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants