{"library":"langcodes","title":"langcodes","description":"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.","status":"active","version":"3.5.1","language":"en","source_language":"en","source_url":"https://github.com/georgkrause/langcodes","tags":["i18n","l10n","language","localization","internationalization","bcp47","iso639","cldr"],"install":[{"cmd":"pip install langcodes","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Requires Python 3.9 or newer.","package":"python","optional":false},{"reason":"Optional data package for language names and statistics, required by methods like .display_name() and .speaking_population(). Install with 'pip install langcodes[data]'.","package":"language-data","optional":true}],"imports":[{"symbol":"Language","correct":"from langcodes import Language"},{"note":"The top-level 'get' function is a convenience alias for Language.get().","symbol":"get","correct":"from langcodes import get"},{"note":"While still importable, 'best_match' is deprecated and relies on older CLDR matching. Use 'closest_match' or 'Language.distance' instead.","wrong":"from langcodes import best_match","symbol":"best_match","correct":"from langcodes import best_match"}],"quickstart":{"code":"from langcodes import Language, standardize_tag, closest_match\n\n# Parse a language tag\nenglish_us = Language.get('en-US')\nprint(f\"Parsed 'en-US': language={english_us.language}, script={english_us.script}, territory={english_us.territory}\")\n\n# Normalize a language tag\nnormalized_tag = standardize_tag('zh-CN')\nprint(f\"Normalized 'zh-CN': {normalized_tag}\")\n\n# Compare languages using distance (lower is better match)\nfrench = Language.get('fr')\ncanadian_french = Language.get('fr-CA')\nprint(f\"Distance between 'fr' and 'fr-CA': {french.distance(canadian_french)}\")\n\n# Find the closest match from a list of supported languages\ndesired = 'en-GB'\nsupported = ['en-US', 'en-AU', 'fr-CA']\nclosest = closest_match(desired, supported)\nprint(f\"Closest match for '{desired}' in {supported}: {closest}\")\n\n# Get display names (requires 'langcodes[data]' to be installed)\ntry:\n    spanish_name_in_english = Language.get('es').display_name('en')\n    print(f\"Name of 'es' in English: {spanish_name_in_english}\")\nexcept ImportError:\n    print(\"Install 'langcodes[data]' (e.g., pip install langcodes[data]) for language names and statistics.\")","lang":"python","description":"Demonstrates parsing, normalizing, comparing language tags using distance, finding closest matches, and retrieving display names (with an optional dependency)."},"warnings":[{"fix":"Use `closest_match` or `Language.distance` for a more accurate measure of language closeness. A lower distance indicates a better match.","message":"The `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.","severity":"deprecated","affected_versions":"Since v2.0; explicitly warned in v3.5.1."},{"fix":"Upgrade your Python environment to 3.9 or newer. The library's `requires_python` is `>=3.9`.","message":"Python 3.8 is no longer supported. Attempting to use `langcodes` on Python 3.8 will likely result in installation failures or unexpected behavior.","severity":"breaking","affected_versions":"Since v3.5.0."},{"fix":"Install `langcodes` with the `data` extra to include this dependency: `pip install langcodes[data]`.","message":"Functions 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`.","severity":"gotcha","affected_versions":"Since v3.0 (when data was moved to a separate package); default install behavior clarified/fixed in v3.5.1."},{"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.","message":"The `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.","severity":"gotcha","affected_versions":"Since v3.4.1."},{"fix":"Update your code to use `territory` instead of `region` for clarity and future compatibility.","message":"The `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.","severity":"deprecated","affected_versions":"Since v2.0 (with deprecation warnings for common cases)."}],"env_vars":null,"last_verified":"2026-04-05T00:00:00.000Z","next_check":"2026-07-04T00:00:00.000Z"}