Skip to main content

vn-text

Correct Unicode primitives for Vietnamese text. No runtime dependencies — standard library only.

pip install vn-text
from vn_text import fold, deaccent, strip_stroke, is_vietnamese

fold('Đặng Minh Anh')     # 'dang minh anh'
fold('Hà Nội, Việt Nam!')  # 'ha noi viet nam'
deaccent('Tiếng Việt')    # 'Tieng Viet'
strip_stroke('Đặng')      # 'Dặng'
is_vietnamese('Nguyễn')   # True

Why

Vietnamese Đ (U+0110) has no canonical decomposition, so NFD cannot fold it. The usual "NFD then strip combining marks" recipe leaves Đặng Minh as Đang Minh — and nobody types Đang to find Đặng, so search quietly returns too few results. The tempting blanket fix also turns the Icelandic letter Ð (U+00D0) into D and corrupts those names.

strip_stroke handles U+0110 and U+0111 explicitly, and nothing else.

Validation

Every function is checked against the shared conformance suite at conformance/vn-text-1.0.0.json — 156 hand-authored cases that the TypeScript port also consumes, so the two implementations cannot drift apart.

The test file runs with or without pytest, because a library whose correctness guarantee depends on a test runner is a library you cannot check on a machine that has no test runner:

python packages/vn-text-py/tests/test_vn_text.py   # stdlib only, nothing to install

pytest packages/vn-text-py/tests -q                     # if you have it

API parity

snake_case is the Python convention, but stripStroke and isVietnamese are exported as aliases so a call site can move between the Python and TypeScript ports without renaming.

Known port risk

fold() classifies characters using str.isalnum(), while the TypeScript port uses \p{L}\p{N}. These agree across all 127 distinct characters in the current corpus, measured by scripts/verify-port-parity.mjs. They are not guaranteed to agree for every code point; the conformance suite is how a divergence gets caught.

Scope

Deliberately narrow. Tone-mark canonicalisation (hóa vs hòa) and fuzzy matching for unaccented-keyboard input are not here. Sorting is not here either -- it is vn-collate, which shares this repository's conformance infrastructure. See the root README for the reasoning.

Licence

MIT

Metadata

Release files for vn-text 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vn-text 0.1.0
File Size Uploaded
vn_text-0.1.0.tar.gz 9.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for vn-text 0.1.0
File Interpreter ABI Platform
vn_text-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 18.8 kB

Release files / vn_text-0.1.0.tar.gz

Download URL vn_text-0.1.0.tar.gz
Size 9.9 kB
Tags Source
SHA-256 checksum
How to use checksums
52f2ccf938bde7e6f90ca546bae2c88c1f2395a4676099f646b8d213ff1c7781
BLAKE2b-256 checksum
How to use checksums
05c622c3c61e790b3f24bed01660a30e08a7d33b8d1594064e2f4e9e56653bae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / vn_text-0.1.0-py3-none-any.whl

Download URL vn_text-0.1.0-py3-none-any.whl
Size 8.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
12d7f3d26487f58525b788a3b2dd7b8a9ea97ca4778d8908ae66781bbc8428a8
BLAKE2b-256 checksum
How to use checksums
dfe71ec49f9dce59c977dcb7fabccb44a04eb0db0a0ac1121bfccccc34db06ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page