Title: Complete rustpython-unicode isolation: case mapping, casing predicates, sre parity by youknowone · Pull Request #8237 · RustPython/RustPython · GitHub
Open Graph Title: Complete rustpython-unicode isolation: case mapping, casing predicates, sre parity by youknowone · Pull Request #8237 · RustPython/RustPython
X Title: Complete rustpython-unicode isolation: case mapping, casing predicates, sre parity by youknowone · Pull Request #8237 · RustPython/RustPython
Description: Follow-up to #7560, completing the rustpython-unicode isolation begun in #8211. Implements #8236. What this does Moves the remaining case mapping and casing predicates out of rustpython-vm into rustpython-unicode, so the crate is the single authoritative Unicode path and crates/unicode becomes the only workspace member with a direct icu4x dependency. Also fixes two long-standing TODO: check with cpython quirks in the SRE engine. Commits Move str casing into rustpython-unicode::case and drop icu from vm — adds code-point simple mappings (simple_lowercase/uppercase/titlecase/fold), casing predicates (is_lowercase/is_uppercase/is_titlecase/is_cased/is_case_ignorable), and string-level capitalize/title/swapcase/casefold helpers. str.rs/anystr.rs route through the crate; icu_casemap/icu_locale/icu_properties/writeable leave crates/vm. str.lower/upper keep using Wtf8::to_lowercase/to_uppercase (no icu, and std already applies the final-sigma rule). Route sre is_uni_space through classify::is_space — replaces the hand-rolled BMP list. A full-range sweep confirms it agrees with the old list on every code point, and classify::is_space is differential-tested against CPython. Use simple case mappings and the Cased property for sre IGNORECASE — lower_unicode/upper_unicode took the first char of the full mapping, miscasing code points with a full but no simple mapping (e.g. upper_unicode('ß') returned 'S'). Now use simple_lowercase/simple_uppercase (Py_UNICODE_TOLOWER/TOUPPER). _sre.unicode_iscased derived casedness from those mappings, which broke the _casefix ligature equivalences (ſt/st) once simple mappings were used; it now queries the Cased property directly. Sweep casing predicates and simple lowercase mapping against CPython — extends the differential harness (full 0..0x110000 range) to the new casing predicates and the simple lowercase mapping, each with its own version-skew allow-list. Records the U+0295 Ll→Lo recategorization (Unicode 16.0.0 → 17.0.0) as a known reverse-direction divergence. Verification crates/unicode unit + differential tests pass; no_std target (thumbv7em-none-eabi) still builds. Regression gate green: test_unicodedata, test_str, test_re, test_pkgutil (run=381). re.IGNORECASE now matches CPython on ß/SS, the ſt/st ligatures, and Kelvin K. Acceptance: crates/unicode is the only workspace member with a direct icu dependency. 🤖 Generated with Claude Code Summary by CodeRabbit New Features Expanded Unicode-aware casing and casefolding for strings, including added one-to-one “simple” case mappings and predicates (lowercase/uppercase/titlecase/cased). Bug Fixes Improved CPython-style final-sigma and titlecasing behavior, plus updated non-ASCII casing checks. Preserves lone surrogate characters correctly in WTF-8 string processing. Tests Added and refreshed Unicode conformance coverage for case mappings and predicates.
Open Graph Description: Follow-up to #7560, completing the rustpython-unicode isolation begun in #8211. Implements #8236. What this does Moves the remaining case mapping and casing predicates out of rustpython-vm into rus...
X Description: Follow-up to #7560, completing the rustpython-unicode isolation begun in #8211. Implements #8236. What this does Moves the remaining case mapping and casing predicates out of rustpython-vm into rus...
Opengraph URL: https://github.com/RustPython/RustPython/pull/8237
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:f64b5159-0629-fbf3-f9d3-1d7b3799e00e |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | BF46:3E096D:3543455:49B709E:6A60DA01 |
| html-safe-nonce | 4061efca747e8232ddcbeeab20a9c65ab457652c7ed3369c04ea8082a62793c3 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCRjQ2OjNFMDk2RDozNTQzNDU1OjQ5QjcwOUU6NkE2MERBMDEiLCJ2aXNpdG9yX2lkIjoiNzQ0NjEzODE3NTU3NzY4NzA1IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 73a60a9fd9abddf565576395cfc22b864995de10fc6dcd6aeefe65f097dabb83 |
| hovercard-subject-tag | pull_request:4012970612 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/RustPython/RustPython/pull/8237/files |
| twitter:image | https://avatars.githubusercontent.com/u/69878?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/69878?s=400&v=4 |
| og:image:alt | Follow-up to #7560, completing the rustpython-unicode isolation begun in #8211. Implements #8236. What this does Moves the remaining case mapping and casing predicates out of rustpython-vm into rus... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 8302bdfafed4cf34ac9c1d3593108fafa53bc3f86b893907e38fa6bdd74361ac |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/RustPython/RustPython git https://github.com/RustPython/RustPython.git |
| octolytics-dimension-user_id | 39710557 |
| octolytics-dimension-user_login | RustPython |
| octolytics-dimension-repository_id | 135201145 |
| octolytics-dimension-repository_nwo | RustPython/RustPython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 135201145 |
| octolytics-dimension-repository_network_root_nwo | RustPython/RustPython |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | c3c2ff0c76b34772c83c9498a08cefee28f53da0 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width