Skip to main content

pyunormalize

The pyunormalize package is a pure-Python, zero-dependency implementation of the Unicode normalization algorithm.

It supports the four standard Unicode normalization forms:

  • NFC
  • NFD
  • NFKC
  • NFKD

The package uses generated lookup tables derived from the Unicode Character Database (UCD) for Unicode 18.0.0, released in September 2026. It is therefore independent of the unicodedata module and the specific Unicode database version bundled with the Python runtime on which it is installed.

All four normalization forms are tested against the official Unicode NormalizationTest.txt test file.

Requirements

Python 3.9 or newer.

Installation

Install the package with:

pip install pyunormalize

Upgrade to the latest version with:

pip install --upgrade pyunormalize

Public API

The public API exposes the four normalization functions and a generic dispatcher:

from pyunormalize import NFC, NFD, NFKC, NFKD, normalize

It also exposes constants for the Unicode version in use:

from pyunormalize import UCD_VERSION, UNICODE_VERSION

Note that UCD_VERSION and UNICODE_VERSION are aliases referring to the same version string ('18.0.0').

Usage examples

Below are practical examples illustrating how to normalize Unicode strings using either dedicated functions or the generic dispatcher.

Dedicated functions

Use the convenience functions NFC, NFD, NFKC, or NFKD for direct normalization:

from pyunormalize import NFC, NFD, NFKC, NFKD

text = "désaffiliât"
assert text == NFC(text)

def hex_repr(string):
    return " ".join([f"{ord(c):04X}" for c in string])

print(f"NFD  : {hex_repr(NFD(text))}")
print(f"NFKD : {hex_repr(NFKD(text))}")

print(f"NFC  : {hex_repr(NFC(text))}")
print(f"NFKC : {hex_repr(NFKC(text))}")

Output:

NFD  : 0064 0065 0301 0073 0061 FB03 006C 0069 0061 0302 0074
NFKD : 0064 0065 0301 0073 0061 0066 0066 0069 006C 0069 0061 0302 0074
NFC  : 0064 00E9 0073 0061 FB03 006C 0069 00E2 0074
NFKC : 0064 00E9 0073 0061 0066 0066 0069 006C 0069 00E2 0074

Generic normalize function

When the normalization form is specified dynamically at runtime, use normalize(form, text):

from pyunormalize import normalize

text = "fluffiness"

# The `form` parameter accepts "NFC", "NFD", "NFKC", or "NFKD" (case-sensitive)
nfkd_text = normalize("NFKD", text)

print(nfkd_text)

Output:

fluffiness

This implementation is based on the following resources:

Changelog

See the CHANGELOG for the latest updates and changes.

Licenses

The code is available under the terms of the MIT License.

The use of Unicode data files is governed by the UNICODE TERMS OF USE. Further specifications of rights and restrictions pertaining to the use of the Unicode data files and software can be found in the Unicode License v3, a copy of which is included as UNICODE-LICENSE.

Release files for pyunormalize 18.0.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 pyunormalize 18.0.0
File Size Uploaded
pyunormalize-18.0.0.tar.gz 575.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyunormalize 18.0.0
File Interpreter ABI Platform
pyunormalize-18.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 653.4 kB

Release files / pyunormalize-18.0.0.tar.gz

Download URL pyunormalize-18.0.0.tar.gz
Size 575.1 kB
Tags Source
SHA-256 checksum
How to use checksums
2b2e65201e688bb38c66ab66ef1071cc07b32e9840e5ae07aab716db6ede7d6d
BLAKE2b-256 checksum
How to use checksums
49645c8ce34a4e366ee052ce7b3b2ddd11b9711a072902a31d0385f3a0f394e8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / pyunormalize-18.0.0-py3-none-any.whl

Download URL pyunormalize-18.0.0-py3-none-any.whl
Size 78.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cdc571ab761c2bd905275c9f3e3cf386d10b4f9bc8d55b32d410cc635e684ba8
BLAKE2b-256 checksum
How to use checksums
fb0a5370bd67bdfc4acf97f25b08cb6fbcb7e898fa391716535c60b4bd761492
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

18.0.0 This release

2 release files

17.0.0

2 release files

16.0.0

2 release files

15.1.0

1 release file

15.0.0

1 release file

14.0.0

1 release file

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