fix: Swapcase must handle multibyte expansions#7559
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthrough
Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Sorry, something went wrong.
📦 Library DependenciesThe following Lib/ modules were modified. Here are their dependencies: [ ] test: cpython/Lib/test/test_str.py (TODO: 16) dependencies: dependent tests: (no tests depend on str) Legend:
|
Sorry, something went wrong.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
crates/vm/src/builtins/str.rs (1)
1044-1059: LGTM! Correct fix for Unicode multi-character case expansions.The change from
to_ascii_uppercase()/to_ascii_lowercase()toto_uppercase()/to_lowercase()withextend()properly handles Unicode case mappings that expand to multiple characters (e.g., "ß" → "SS", or "ı" → "I"). Theshrink_to_fit()call is appropriate since the initial capacity may over-allocate for potential expansions that don't always occur.Minor terminology nit: the comment at line 1048 says "multiple bytes" but technically
to_uppercase()returns an iterator because case changes may produce multiple characters (code points), not bytes. Each character is then encoded to its byte representation.📝 Optional comment clarification
- // to_uppercase returns an iterator because case changes may be multiple bytes + // to_uppercase returns an iterator because case changes may produce multiple characters,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/vm/src/builtins/str.rs` around lines 1044 - 1059, Update the inline comment inside the swapcase method to accurately describe why to_uppercase()/to_lowercase() return an iterator: change "multiple bytes" to "multiple characters (code points)" or similar; the correction should be made in the comment immediately above the if-block that calls c.to_uppercase() and c.to_lowercase() in the swapcase function (referencing swapcase, c_orig, to_uppercase, to_lowercase).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@crates/vm/src/builtins/str.rs`:
- Around line 1044-1059: Update the inline comment inside the swapcase method to
accurately describe why to_uppercase()/to_lowercase() return an iterator: change
"multiple bytes" to "multiple characters (code points)" or similar; the
correction should be made in the comment immediately above the if-block that
calls c.to_uppercase() and c.to_lowercase() in the swapcase function
(referencing swapcase, c_orig, to_uppercase, to_lowercase).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: da2da0a5-1571-4e3b-97c0-44307ec105b2
⛔ Files ignored due to path filters (1)
Lib/test/test_str.pyis excluded by!Lib/**
📒 Files selected for processing (1)
crates/vm/src/builtins/str.rs
Sorry, something went wrong.
youknowone
left a comment
There was a problem hiding this comment.
Thank you for contributing! welcome to RustPython project
Sorry, something went wrong.
d749d6f to
0fc94a8
Compare
April 5, 2026 19:01
`swapcase` used `to_ascii_lowercase` and uppercase to swap cases. This is fine for ASCII, but code points may expand into multiple bytes which leads to incorrect case swaps for some languages. The fix is to use `to_lowercase` and `to_uppercase` instead. Unfortunately, this leads to a realloc in `swapcase` when bytes are expanded. Part of RustPython#7526.
0fc94a8 to
2e1a0f4
Compare
April 6, 2026 02:12
ShaharNaveh
left a comment
There was a problem hiding this comment.
LGTM!
tysm:)
Sorry, something went wrong.
youknowone
left a comment
There was a problem hiding this comment.
👍
Sorry, something went wrong.
e009cc0
into
RustPython:main
Apr 6, 2026
swapcaseusedto_ascii_lowercaseand uppercase to swap cases. This is fine for ASCII, but code points may expand into multiple bytes which leads to incorrect case swaps for some languages. The fix is to useto_lowercasedirectly.Unfortunately, this leads to a realloc in
swapcasewhen bytes are expanded.Part of #7526.
Most of the disabled swapcase tests seem to pass now including the new assert based on #7526. However, there are other areas where
to_ascii_lowercaseandto_ascii_uppercaseare used which seem to be causing the other cases to fail.Summary by CodeRabbit