Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions babel/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
'Locale',
'UnknownLocaleError',
'default_locale',
'get_cldr_version',
'get_global',
'get_locale_identifier',
'negotiate_locale',
Expand All @@ -33,6 +34,7 @@

_GLOBAL_KEY: TypeAlias = Literal[
"all_currencies",
"cldr",
"currency_fractions",
"language_aliases",
"likely_subtags",
Expand Down Expand Up @@ -80,6 +82,7 @@ def get_global(key: _GLOBAL_KEY) -> Mapping[str, Any]:
The keys available are:

- ``all_currencies``
- ``cldr`` (metadata)
- ``currency_fractions``
- ``language_aliases``
- ``likely_subtags``
Expand Down Expand Up @@ -1363,3 +1366,19 @@ def get_locale_identifier(
lang, territory, script, variant, modifier = tup + (None,) * (5 - len(tup))
ret = sep.join(filter(None, (lang, script, territory, variant)))
return f'{ret}@{modifier}' if modifier else ret


def get_cldr_version() -> str:
"""Return the Unicode CLDR version used by this Babel installation.

Generally, you should be able to assume that the return value of this

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What other values can it have?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, I'm pre-planning for a downstream distro to do something weird here like "27+deb1". 😀

Copy link

@bartfeenstra bartfeenstra Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha okay. My original request was to be able to link to version-specific CLDR docs so as long as there is some way to reliably get just the 27 part (either a separate function or by parsing a more complex value) that would support my use case :)

Happy holidays! 🎄😊

function is a string representing a version number, e.g. '47'.

>>> get_cldr_version()
'47'

.. versionadded:: 2.18

:rtype: str
"""
return str(get_global("cldr")["version"])
2 changes: 2 additions & 0 deletions docs/api/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ Utility Functions
.. autofunction:: parse_locale

.. autofunction:: get_locale_identifier

.. autofunction:: get_cldr_version
13 changes: 13 additions & 0 deletions scripts/import_cldr.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,19 @@ def process_data(srcdir, destdir, force=False, dump_json=False):

def parse_global(srcdir, sup):
global_data = {}

with open(os.path.join(srcdir, 'dtd', 'ldml.dtd')) as dtd_file:
cldr_version_match = re.search(
r'<!ATTLIST version cldrVersion CDATA #FIXED "(.+?)"',
dtd_file.read(),
)
if not cldr_version_match:
raise ValueError("Could not find CLDR version in DTD file")
cldr_version = cldr_version_match.group(1)
global_data.setdefault('cldr', {})['version'] = cldr_version

log.info('Processing CLDR version %s from %s', cldr_version, srcdir)

sup_dir = os.path.join(srcdir, 'supplemental')
territory_zones = global_data.setdefault('territory_zones', {})
zone_aliases = global_data.setdefault('zone_aliases', {})
Expand Down
4 changes: 4 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,3 +402,7 @@ def test_locale_parse_empty():
Locale.parse(None)
with pytest.raises(TypeError, match="Empty"):
Locale.parse(False) # weird...!


def test_get_cldr_version():
assert core.get_cldr_version() == "47"
Loading