René's URL Explorer Experiment


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

direct link

Domain: github.com

route-pattern/:user_id/:repository/pull/:id/files(.:format)
route-controllerpull_requests
route-actionfiles
fetch-noncev2:f64b5159-0629-fbf3-f9d3-1d7b3799e00e
current-catalog-service-hashae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b
request-idBF46:3E096D:3543455:49B709E:6A60DA01
html-safe-nonce4061efca747e8232ddcbeeab20a9c65ab457652c7ed3369c04ea8082a62793c3
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCRjQ2OjNFMDk2RDozNTQzNDU1OjQ5QjcwOUU6NkE2MERBMDEiLCJ2aXNpdG9yX2lkIjoiNzQ0NjEzODE3NTU3NzY4NzA1IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0=
visitor-hmac73a60a9fd9abddf565576395cfc22b864995de10fc6dcd6aeefe65f097dabb83
hovercard-subject-tagpull_request:4012970612
github-keyboard-shortcutsrepository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///pull_requests/show/files
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/RustPython/RustPython/pull/8237/files
twitter:imagehttps://avatars.githubusercontent.com/u/69878?s=400&v=4
twitter:cardsummary_large_image
og:imagehttps://avatars.githubusercontent.com/u/69878?s=400&v=4
og:image:altFollow-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_nameGitHub
og:typeobject
hostnamegithub.com
expected-hostnamegithub.com
None8302bdfafed4cf34ac9c1d3593108fafa53bc3f86b893907e38fa6bdd74361ac
turbo-cache-controlno-preview
diff-viewunified
go-importgithub.com/RustPython/RustPython git https://github.com/RustPython/RustPython.git
octolytics-dimension-user_id39710557
octolytics-dimension-user_loginRustPython
octolytics-dimension-repository_id135201145
octolytics-dimension-repository_nwoRustPython/RustPython
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id135201145
octolytics-dimension-repository_network_root_nwoRustPython/RustPython
turbo-body-classeslogged-out env-production page-responsive full-width
disable-turbotrue
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
releasec3c2ff0c76b34772c83c9498a08cefee28f53da0
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/RustPython/RustPython/pull/8237/files#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FRustPython%2FRustPython%2Fpull%2F8237%2Ffiles
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub Copilot appDirect agents from issue to mergehttps://github.com/features/ai/github-app
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
Code QualityEnforce quality at mergehttps://github.com/features/code-quality
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
View all resourceshttps://github.com/resources
GitHub SponsorsFund open source developershttps://github.com/open-source/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/open-source/accelerator
GitHub Starshttps://stars.github.com
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/enterprise/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FRustPython%2FRustPython%2Fpull%2F8237%2Ffiles
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fpull_requests%2Fshow%2Ffiles&source=header-repo&source_repo=RustPython%2FRustPython
Reloadhttps://github.com/RustPython/RustPython/pull/8237/files
Reloadhttps://github.com/RustPython/RustPython/pull/8237/files
Reloadhttps://github.com/RustPython/RustPython/pull/8237/files
Please reload this pagehttps://github.com/RustPython/RustPython/pull/8237/files
RustPython https://github.com/RustPython
RustPythonhttps://github.com/RustPython/RustPython
Notifications https://github.com/login?return_to=%2FRustPython%2FRustPython
Fork 1.5k https://github.com/login?return_to=%2FRustPython%2FRustPython
Star 22.2k https://github.com/login?return_to=%2FRustPython%2FRustPython
Code https://github.com/RustPython/RustPython
Issues 293 https://github.com/RustPython/RustPython/issues
Pull requests 102 https://github.com/RustPython/RustPython/pulls
Discussions https://github.com/RustPython/RustPython/discussions
Actions https://github.com/RustPython/RustPython/actions
Projects https://github.com/RustPython/RustPython/projects
Models https://github.com/RustPython/RustPython/models
Wiki https://github.com/RustPython/RustPython/wiki
Security and quality 0 https://github.com/RustPython/RustPython/security
Insights https://github.com/RustPython/RustPython/pulse
Code https://github.com/RustPython/RustPython
Issues https://github.com/RustPython/RustPython/issues
Pull requests https://github.com/RustPython/RustPython/pulls
Discussions https://github.com/RustPython/RustPython/discussions
Actions https://github.com/RustPython/RustPython/actions
Projects https://github.com/RustPython/RustPython/projects
Models https://github.com/RustPython/RustPython/models
Wiki https://github.com/RustPython/RustPython/wiki
Security and quality https://github.com/RustPython/RustPython/security
Insights https://github.com/RustPython/RustPython/pulse
Sign up for GitHub https://github.com/signup?return_to=%2FRustPython%2FRustPython%2Fissues%2Fnew%2Fchoose
terms of servicehttps://docs.github.com/terms
privacy statementhttps://docs.github.com/privacy
Sign inhttps://github.com/login?return_to=%2FRustPython%2FRustPython%2Fissues%2Fnew%2Fchoose
youknowonehttps://github.com/youknowone
RustPython:mainhttps://github.com/RustPython/RustPython/tree/main
youknowone:unicodehttps://github.com/youknowone/RustPython/tree/unicode
Conversation 4 https://github.com/RustPython/RustPython/pull/8237
Commits 4 https://github.com/RustPython/RustPython/pull/8237/commits
Checks 25 https://github.com/RustPython/RustPython/pull/8237/checks
Files changed https://github.com/RustPython/RustPython/pull/8237/files
Please reload this pagehttps://github.com/RustPython/RustPython/pull/8237/files
Complete rustpython-unicode isolation: case mapping, casing predicates, sre parity https://github.com/RustPython/RustPython/pull/8237/files#top
Show all changes 4 commits https://github.com/RustPython/RustPython/pull/8237/files
27f8047 Move str casing into rustpython-unicode::case and drop icu from vm youknowone Jul 8, 2026 https://github.com/RustPython/RustPython/pull/8237/commits/27f8047f810e0acc5e8e636ba48b7809c0964a29
1c0e2bd Route sre is_uni_space through unicode::classify::is_space youknowone Jul 8, 2026 https://github.com/RustPython/RustPython/pull/8237/commits/1c0e2bd5029e08a1bfea2848db5ee95f9e440b18
e5385d8 Use simple case mappings and the Cased property for sre IGNORECASE youknowone Jul 8, 2026 https://github.com/RustPython/RustPython/pull/8237/commits/e5385d80d39d9437a21262786ea69c1ea7808616
37f2727 Sweep casing predicates and simple lowercase mapping against CPython youknowone Jul 8, 2026 https://github.com/RustPython/RustPython/pull/8237/commits/37f27271bb5ddc3af8518ad1ebb6173c26a03538
Clear filters https://github.com/RustPython/RustPython/pull/8237/files
Please reload this pagehttps://github.com/RustPython/RustPython/pull/8237/files
Please reload this pagehttps://github.com/RustPython/RustPython/pull/8237/files
Cargo.lock https://github.com/RustPython/RustPython/pull/8237/files#diff-13ee4b2252c9e516a0547f2891aa2105c3ca71c6d7a1e682c69be97998dfc87e
string.rs https://github.com/RustPython/RustPython/pull/8237/files#diff-02c1acfdbc47f1c203f53fcd964ecd4991e001d584d8905e1cee1a7eef88009d
Cargo.toml https://github.com/RustPython/RustPython/pull/8237/files#diff-7f3a442136bd9e1ed84129215164ccaecf56d1ce7aefe5cc0470be85acfe0a6d
case.rs https://github.com/RustPython/RustPython/pull/8237/files#diff-be3ce82912f4945758b0b76567641500bd0a493a61307e4b98743cf392591f6e
cpython3.14_mappings.txt https://github.com/RustPython/RustPython/pull/8237/files#diff-f2ade66c926a20a3591cf2af1cd85a890972d5f32c351ced8c42c4c7a0f72f2e
cpython3.14_predicates.txt https://github.com/RustPython/RustPython/pull/8237/files#diff-e4dec6f43c7b0e6cbd51e933aa1a1e98e33b9af06ef9471434be5cd330102c12
version_skew_cpython3.14.txt https://github.com/RustPython/RustPython/pull/8237/files#diff-b5a872cb64d78cf4dedf57da81a74da841bae0451a57fc5f2378e67bd955b317
version_skew_mappings_cpython3.14.txt https://github.com/RustPython/RustPython/pull/8237/files#diff-d8359d01288c4342ada9122cb23d86b37dcce1c50ce3bf6b872f512a9b144d24
differential.rs https://github.com/RustPython/RustPython/pull/8237/files#diff-0e3ea436b7fd77ab8ceb1791170b869813347b84e7c93ecfb6ff1070bd22e959
generate_reference.py https://github.com/RustPython/RustPython/pull/8237/files#diff-dc80788fc4a3a6f1db7411bb15320a04db341faa6cbfcb525a764f4e89e22f2c
Cargo.toml https://github.com/RustPython/RustPython/pull/8237/files#diff-ccc3290f8eb6dbc476c8aad5c1586bf96837946b852e683ee8f21e4df91dc140
anystr.rs https://github.com/RustPython/RustPython/pull/8237/files#diff-dd35a1000e2e6c0e7e4310bf9339045337d1db8ef9795c3cd7f2dbbb8f3dd809
str.rs https://github.com/RustPython/RustPython/pull/8237/files#diff-a04ea1f7734fe40189e756196e034e6dedfcd5c82f2925e58cfd51ba7432073a
_sre.rs https://github.com/RustPython/RustPython/pull/8237/files#diff-62bafdd789f1a10e570be6dbf27f34faa786ff709b0fadcad41dbad4ab206e06
utils.rs https://github.com/RustPython/RustPython/pull/8237/files#diff-94f43400e88f5d9d90b840cddc93f6bcb4355867bbfcedff27412b53c0222db4
Cargo.lockhttps://github.com/RustPython/RustPython/pull/8237/files#diff-13ee4b2252c9e516a0547f2891aa2105c3ca71c6d7a1e682c69be97998dfc87e
View file https://github.com/youknowone/RustPython/blob/37f27271bb5ddc3af8518ad1ebb6173c26a03538/Cargo.lock
Open in desktop https://desktop.github.com
how customized files appear on GitHubhttps://docs.github.com/github/administering-a-repository/customizing-how-changed-files-appear-on-github
Please reload this pagehttps://github.com/RustPython/RustPython/pull/8237/files
crates/sre_engine/src/string.rshttps://github.com/RustPython/RustPython/pull/8237/files#diff-02c1acfdbc47f1c203f53fcd964ecd4991e001d584d8905e1cee1a7eef88009d
View file https://github.com/youknowone/RustPython/blob/37f27271bb5ddc3af8518ad1ebb6173c26a03538/crates/sre_engine/src/string.rs
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/RustPython/RustPython/pull/8237/{{ revealButtonHref }}
https://github.com/RustPython/RustPython/pull/8237/files#diff-02c1acfdbc47f1c203f53fcd964ecd4991e001d584d8905e1cee1a7eef88009d
https://github.com/RustPython/RustPython/pull/8237/files#diff-02c1acfdbc47f1c203f53fcd964ecd4991e001d584d8905e1cee1a7eef88009d
crates/unicode/Cargo.tomlhttps://github.com/RustPython/RustPython/pull/8237/files#diff-7f3a442136bd9e1ed84129215164ccaecf56d1ce7aefe5cc0470be85acfe0a6d
View file https://github.com/youknowone/RustPython/blob/37f27271bb5ddc3af8518ad1ebb6173c26a03538/crates/unicode/Cargo.toml
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/RustPython/RustPython/pull/8237/{{ revealButtonHref }}
https://github.com/RustPython/RustPython/pull/8237/files#diff-7f3a442136bd9e1ed84129215164ccaecf56d1ce7aefe5cc0470be85acfe0a6d
https://github.com/RustPython/RustPython/pull/8237/files#diff-7f3a442136bd9e1ed84129215164ccaecf56d1ce7aefe5cc0470be85acfe0a6d
Please reload this pagehttps://github.com/RustPython/RustPython/pull/8237/files
Please reload this pagehttps://github.com/RustPython/RustPython/pull/8237/files
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.