Skip to content

Replace Unihan with Wikidata for locales.ZH's simplified forms and the suggester's pinyin - #1371

Merged
derek73 merged 9 commits into
masterfrom
fix/replace-unihan-with-wikidata
Nov 13, 2026
Merged

derek73 merged 9 commits into
masterfrom
fix/replace-unihan-with-wikidata

Conversation

@derek73

@derek73 derek73 commented Nov 13, 2026 •

Copy link
Copy Markdown
Owner

Based on master since #1370 merged (master merged in; the tree is unchanged from the reviewed commits).

What

No shipped data derives from Unihan any more, so Unicode-3.0 leaves the licence expression and LICENSE-unicode leaves the tree. This settles the Open item in #1370's FACTS WE MEASURE entry for Unicode-3.0. It does not settle #981 (a mainland-weighted third ranking). W1's Open line now notes that such a ranking would restore the 7 dropped forms.

  • locales.ZH's simplified surname forms (tools/zh_surnames.py): a ranked traditional form gains the one simplified form given by the simplified-Chinese labels (zh-hans, zh-cn, zh-sg, zh-my) of the Wikidata items labelled with it (CC0). The items are every family name (Q101352) and every Chinese family name (Q1093580): 關, 顏 and 遲 have items of the first class only. It is the rule Unihan's variant table was read by: exactly one form, in the BMP, and not the form itself.
  • The group suggester's pinyin surnames (tools/vocab/order_names.py): every Hanyu Pinyin reading that Wikidata's family-name items state for each locales.ZH single-character surname, read from three statements. They are P2440 qualified by P459 = Hanyu Pinyin (Q42222), the P1721 qualifier of P1705, and the P1705 of the Latin-script item that P460 names under P1013 = Q42222. A surname with no reading is left out, and the run names it: 35 of 463.
  • Both tools key their Wikidata cache by the exact queries they send, ask in batches of 100, and refuse an answer that holds a row which is not a real row. That last case is how the query service's error text reads when it cuts a CSV answer short at its time limit; this PR's first run hit it.

Moves

locales.ZH. The block holds 317 forms, down from 324. 12 of the 19 forms only Unihan supplied are attested by Wikidata: 东云兰关区娄盘练迟阙颜风. The other 7 are not, and they leave: 买厐盖篮芈诸谌.

  • I compared the two trees over every name that holds a Han character in the committed and local corpora: config_diff.py diff --committed --local all --match '[一-鿿㐀-䶿]' --readings <file> default plain:ZH, run in each tree, with the files compared line by line.
  • 9 of 322,895 names moved. All 9 are transliterated foreign names that begin with 盖, such as 盖尔哈尔德 (Gerhard) and 盖达尔 阿利耶夫 (Heydar Aliyev). The pack used to cut them after 盖; now they read as the default does.
  • The cost is real Chinese names with one of the 7 surnames written in simplified characters. 谌龙 (Chen Long) now reads undivided, as family 谌龙. Written in traditional characters (諶龍), the name still divides.
  • cldr_agreement.py: no record moved, the CLDR and Wikidata-native locale views included.

Pinyin. The block holds 200 spellings, down from 206.

  • Joined: zeng, shan, zha, zhai, bu, nian. These are the surname readings of 曾, 单, 查, 翟, 卜, 粘, where Unihan's first kMandarin reading gave ceng, dan, cha, di, bo, zhan.
  • Left: an, bing, bo, ceng, cha, chou, dan, diao, jie, kou, nong, que. an stays in the table through the Korean list.
  • The given-name table did not move.

Suggester. suggest_measure.py --base <e9cb3520>:

  • 59 cells of the order table moved: 54 up and 5 down, each down by one group in 300.
  • The largest move is PSC's Chinese filers written given-first under a family-first base: 59.7 / 84.3 / 91.7 / 94.7% became 63.0 / 85.7 / 92.3 / 96.0% at 2 to 5 names.
  • No same-order cell fell, and the worst same-order row outside the three anti-goal rows still reads 98%.
  • No population's first size at 95% moved, so the figures quoted in Parser.suggest, docs/suggest.rst and decisions/group-suggestion stand.

Docs

  • decisions/shipped-data-licences: a 2026-11-12 UNIHAN REPLACED entry and a Standing line. It keeps the record that 2.5.0 through 3.0.1 shipped Unihan-derived forms.
  • decisions/group-suggestion: a PINYIN FROM WIKIDATA entry, plus a head note on the TABLES entry.
  • decisions/W1: a log entry, plus a head note on the 柯洁 reads as one family name under locales.ZH: should the Chinese surname list go past the census top 100? #695 entry.
  • Also updated: AGENTS.md's "Shipping data" paragraph, README's License section, zh.py's and _order_names.py's provenance, and a release-log bullet.

Checks

  • uv run pytest: 46,827 passed, 38 skipped, 3 xfailed.
  • uv run pytest -n0 -m serial: 38 passed.
  • uv run mypy and uv run ruff check: clean.

Reviews

  • design-docs-reviewer on the docs/design changes. It found a cell count that counted listing lines, an missing, three anti-goal rows written as two, superseded entries without head notes, and AGENTS.md. All fixed.
  • pr-review-toolkit code-reviewer. It found that the cache key ignored the query, the item that writes a form the same in both scripts, untested loaders, and the release-log wording. All fixed. Fixing it uncovered the cut-answer case.
  • A second code-reviewer pass on the fix commit. It found that the order_names tests patched a copy of name_usage other than the one ask calls (in one collection order they reached the network), and that the pinyin cache test passed on the parent code. It also found that an empty pinyin batch was refused. All fixed in the third commit.

🤖 Generated with Claude Code

derek73 and others added 6 commits November 12, 2026 20:47
The licence expression read LGPL-2.1-or-later alone while the wheel
ships data under five other licences. It now reads
LGPL-2.1-or-later AND Apache-2.0 AND GFDL-1.2-no-invariants-or-later
AND CC-BY-4.0 AND OGDL-Taiwan-1.0 AND Unicode-3.0.

- LICENSE-nam_dict: nam_dict's notices and the GFDL 1.2 text, which
  its terms ask to travel with the familiar forms and the suggester's
  common given names and which no file in the tree held.
- LICENSE-unicode: the Unicode License v3 notice for the Unihan data,
  in locales/zh.py's simplified surname forms since 2.5.0 and in the
  suggester's pinyin surnames; zh.py's docstring now credits it.
- README.rst's License section lists every source.
- tests/v2/test_licensing.py holds the licence files, license-files,
  the expression, the README and the crediting modules together.
- decisions/shipped-data-licences records the sources, what each
  licence asks and how it is met; AGENTS.md says what a new source
  needs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Data the project derives by measuring is its own, its sources credited
as a courtesy; a curated list copied whole keeps its licence. Under
that rule nam_dict's familiar-form pairs are dropped before 3.1 and
rebuilt from CC0 data reviewed by hand.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…in surnames

locales.ZH's simplified surname forms now come from the simplified-
Chinese labels of Wikidata's family-name items, and the group
suggester's pinyin surnames from those items' Hanyu Pinyin statements,
both CC0, so the package ships no Unihan-derived data and Unicode-3.0
and LICENSE-unicode leave its licence metadata.

Seven simplified forms no Wikidata item attests (买厐盖篮芈诸谌) leave
locales.ZH; over 322,895 corpus names holding a Han character, 9 move,
all foreign names the pack had cut after 盖. The pinyin block holds
the surname readings (曾 zeng, 单 shan) where Unihan's first reading
gave ceng and dan; suggest_measure moved 37 cells, no quoted figure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the review's doc findings

Both tools reused a cached answer whenever it covered the forms asked,
whatever the query; each now reuses only the answer to the exact
queries it writes, asks in batches of 100 (the whole set outran the
service's time limit), and refuses an answer holding a row that is not
one, which is how the service's error text reads when it cuts a CSV
answer short. A form an item writes the same in both scripts now
counts as its own simplified form, as Unihan's table listed it, so it
leaves the form two candidates; the shipped blocks do not move.

The group-suggestion entry counted listing lines, not cells (59 moved,
54 up, 5 down), left out `an` and named two anti-goal rows of three;
the #695 and TABLES entries get head notes, AGENTS.md says Unihan has
left, and the release-log bullet says what 2.5.0-3.0.1 declared.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… batch be empty

The order_names tests patched tool.name_usage, but ask() calls the
name_usage zh_surnames holds, which another test module's loader can
make a different object, sending the tests to Wikidata; they now patch
that copy and refuse the network. The pinyin cache test now asks a
subset of what it cached, the case the parent answered from the cache,
and a changed pinyin query. A batch of 100 items may hold none with a
reading, so an empty pinyin batch is an answer. W1's Open line records
that #981's mainland ranking would restore the seven dropped forms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73 derek73 added vocabulary Fixed by a word-list entry: per-word vocabulary and language packs locale-packs Locale packs and language choices (nameparser.locales) suggester The group suggester: Parser.suggest() and its signals labels Nov 13, 2026
@derek73 derek73 self-assigned this Nov 13, 2026
Base automatically changed from fix/licence-metadata-familiar-data to master November 13, 2026 05:53
derek73 and others added 3 commits November 12, 2026 22:03
…with-wikidata

# Conflicts:
#	AGENTS.md
#	README.rst
#	docs/design/decisions/shipped-data-licences.md
#	docs/release_log.rst
#	nameparser/locales/zh.py
#	pyproject.toml
#	tests/v2/test_licensing.py
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…with-wikidata

# Conflicts:
#	README.rst
#	docs/design/decisions/shipped-data-licences.md
@derek73
derek73 merged commit b088da4 into master Nov 13, 2026
14 checks passed
@derek73
derek73 deleted the fix/replace-unihan-with-wikidata branch November 13, 2026 06:36
@derek73 derek73 added this to the 3.1 milestone Nov 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

locale-packs Locale packs and language choices (nameparser.locales) suggester The group suggester: Parser.suggest() and its signals vocabulary Fixed by a word-list entry: per-word vocabulary and language packs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant