DEV Community

Toolkit Labs
Toolkit Labs

Posted on

300 Unicode strings where len() lies — 20 are free and scored in one Python file

I built a 300-case labelled corpus of Unicode strings that break naive text handling — combining marks, ZWJ sequences, astral codepoints, bidi controls, zero-width characters, homoglyphs, NFKC folds, case mapping traps, and exotic whitespace. Twenty cases are free (CC0). The rest are EUR 19 on toolkitlabs.org.

This is not a Unicode conformance suite. ICU and the UCD own that job. This corpus answers a narrower production question: what does your len(), truncate, fold, and normalize code actually do on strings a user can paste?

Reproduce the free slice in three commands

curl -sLO https://toolkitlabs.org/unicode300/open20.jsonl?s=devto-4479156
curl -sLO https://toolkitlabs.org/unicode300/check.py
curl -sLO https://toolkitlabs.org/unicode300/controls.py
python3 check.py --fn controls:ascii_fold --cases open20.jsonl
Enter fullscreen mode Exit fullscreen mode

open20.jsonl is 14,387 bytes — two cases per category, the lowest ids in each. check.py runs your function over every case and counts three failure modes: raised, returned non-string, or returned a string that disagrees with the labelled trap on the properties the case is meant to test.

What the three shipped controls do on all 300

I ran the published controls against the full corpus (not just the open 20). Numbers below are from the site's published table, one run, nothing tuned after:

control failures on 300
controls:ascii_fold 247
controls:codepoint_len 198
controls:nfc_then_len 156

The point is not that any control is "good." The point is that different naive handlers fail on different subsets, and you cannot infer coverage from one happy-path emoji test.

A case that breaks len() alone

From open20.jsonl, case u300-0001:

{"id":"u300-0001","string":"cafe\u0301","trap":"len() counts codepoints, not what a reader sees..."}
Enter fullscreen mode Exit fullscreen mode

Five codepoints, four NFC codepoints, six UTF-8 bytes. Truncating to four codepoints can leave a combining acute standing alone.

What EUR 19 buys (and what stays free forever)

  • Free forever: open20.jsonl, check.py, controls.py, scorer docs — CC0, no account.
  • EUR 19 one-time: the other 280 labelled cases as JSONL, flat CSV with measured properties, and corpus SHA-256 e3e1c76e836bd259c571967f0210bc7cd1e081b808720b137ae0cafed934b780 over the 300-line JSONL exactly as shipped.

UNICODE-300 on Toolkit Labs · Buy — EUR 19

Everything on the page reproduces without the paid file: the free zip, the open slice, and the checker are enough to score your own function before you buy anything.

Top comments (0)