Registry / serialization / langcodes

langcodes

JSON →
library3.5.1pypypi✓ verified 33d ago

langcodes is a Python library (current version 3.5.1) that provides tools for parsing, manipulating, and comparing IETF language tags (BCP 47), which are used to identify human languages. It offers robust support for language identification and normalization, implementing standards like ISO 639 and Unicode CLDR. The library maintains an active release cadence, with minor versions released periodically.

pip install langcodes
INSTALL
IMPORT
SIG · LANGCODES
L
langcodes
serializationpythonv3.5.1
Install
1.6s avg
Import
328ms
Disk
17MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.9–3.13
musl
3.9–3.13
Install & Compatibility
Where this runs
tested against v3.5.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.324s · 19.1MB
glibc
py 3.10–3.95 runs
installs and imports cleanly · install 1.6s · import 0.332s · 20MB
17MB installed
● package 17MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Language
✓ from langcodes import Language
get
✓ from langcodes import get
The top-level 'get' function is a convenience alias for Language.get().
best_match
✓ from langcodes import best_match
✗ from langcodes import best_match
While still importable, 'best_match' is deprecated and relies on older CLDR matching. Use 'closest_match' or 'Language.distance' instead.

Demonstrates parsing, normalizing, comparing language tags using distance, finding closest matches, and retrieving display names (with an optional dependency).

from langcodes import Language, standardize_tag, closest_match # Parse a language tag english_us = Language.get('en-US') print(f"Parsed 'en-US': language={english_us.language}, script={english_us.script}, territory={english_us.territory}") # Normalize a language tag normalized_tag = standardize_tag('zh-CN') print(f"Normalized 'zh-CN': {normalized_tag}") # Compare languages using distance (lower is better match) french = Language.get('fr') canadian_french = Language.get('fr-CA') print(f"Distance between 'fr' and 'fr-CA': {french.distance(canadian_french)}") # Find the closest match from a list of supported languages desired = 'en-GB' supported = ['en-US', 'en-AU', 'fr-CA'] closest = closest_match(desired, supported) print(f"Closest match for '{desired}' in {supported}: {closest}") # Get display names (requires 'langcodes[data]' to be installed) try: spanish_name_in_english = Language.get('es').display_name('en') print(f"Name of 'es' in English: {spanish_name_in_english}") except ImportError: print("Install 'langcodes[data]' (e.g., pip install langcodes[data]) for language names and statistics.")
Debug
Known issues
deprecatedThe `best_match` function and other `_score` methods (e.g., `Language.match_score`) are deprecated. They rely on older CLDR matching tables, which are less accurate than the distance-based comparisons introduced later.
fix
Use `closest_match` or `Language.distance` for a more accurate measure of language closeness. A lower distance indicates a better match.
affects: Since v2.0; explicitly warned in v3.5.1.
breakingPython 3.8 is no longer supported. Attempting to use `langcodes` on Python 3.8 will likely result in installation failures or unexpected behavior.
fix
Upgrade your Python environment to 3.9 or newer. The library's `requires_python` is `>=3.9`.
affects: Since v3.5.0.
gotchaFunctions requiring language names (e.g., `Language.display_name()`) or population data now rely on the optional `language-data` package, which is *not* installed by default as of v3.5.1. Attempting to use these features without the optional package will raise an `ImportError`.
fix
Install `langcodes` with the `data` extra to include this dependency: `pip install langcodes[data]`.
affects: Since v3.0 (when data was moved to a separate package); default install behavior clarified/fixed in v3.5.1.
gotchaThe `Language.__hash__` method was reworked in v3.4.1 to correctly account for all language variations. If you relied on specific hash values or used `Language` objects in sets/dictionaries and persisted/reloaded them across v3.4.1 without re-hashing, you might encounter unexpected behavior due to changed hash values.
fix
Ensure `Language` objects are re-hashed or re-created from strings when upgrading from versions prior to 3.4.1 if their hash values are critical to your application logic. As `Language` objects are immutable once created, this primarily affects persistence scenarios or cases where objects are long-lived across upgrades.
affects: Since v3.4.1.
deprecatedThe `region` parameter, dictionary key, and attribute for `Language` objects were renamed to `territory` to align with CLDR and IANA standards. While some backward compatibility with deprecation warnings exists, relying on `region` is discouraged.
fix
Update your code to use `territory` instead of `region` for clarity and future compatibility.
affects: Since v2.0 (with deprecation warnings for common cases).
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'language_data'
Certain functionalities of `langcodes`, particularly those involving language names and detailed data, require the optional `language_data` package, which is not installed by default with `langcodes` itself.
fix
Install the `language_data` package separately, or install `langcodes` with its 'data' extra: `pip install language_data` or `pip install langcodes[data]`
langcodes.tag_parser.LanguageTagError: This script subtag, 'latn', is out of place. Expected variant, extension, or end of string.
This error occurs when a language tag string is malformed or does not adhere to the BCP 47 standard's expected order of subtags, such as placing a script subtag after a territory subtag.
fix
Ensure the language tag follows BCP 47 conventions, specifically the order of subtags (language-script-territory-variant). For example, 'spa-latn-mx' is valid, while 'spa-mx-latn' is not. The correct tag would be `es-Latn-MX` or simply `es-MX`.
LookupError: 'un' is not a known language code, and has no alpha3 code.
This error arises when attempting to retrieve an ISO 639-2 (alpha3) code for a language tag that is either unknown, invalid, or for which `langcodes` does not have a corresponding 3-letter code mapping.
fix
Verify that the language code being queried is a valid IANA-registered language subtag. If it's a private-use tag (e.g., 'x-private'), it won't have a standard alpha3 code. Ensure the code exists and has an alpha3 mapping in the `langcodes` database. For example, `Language.get('en').to_alpha3()` works for 'en'.
AttributeError: 'Language' object has no attribute 'region'
In `langcodes` version 2.0 and later, the attribute for a region code was renamed from `region` to `territory` to align with Unicode CLDR terminology. Code written for older versions will encounter this error.
fix
Update your code to use the `territory` attribute instead of `region`. For example, change `lang.region` to `lang.territory`.
Upgrade
Version history
3.5.1latest on PyPI · released Dec 2, 2025
Audit
Dependencies
pythonrequiredRequires Python 3.9 or newer.
language-dataoptionalOptional data package for language names and statistics, required by methods like .display_name() and .speaking_population(). Install with 'pip install langcodes[data]'.
Agent activity
9 hits · last 30 days
node
8
Resources
langcodes — pip install langcodes · libregistry