Skip to content

Commit

Permalink
Replace babel.localedata.locale_identifiers cache with LRU cache
Browse files Browse the repository at this point in the history
  • Loading branch information
akx committed Feb 7, 2023
1 parent 221c937 commit 08af5e2
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 21 deletions.
23 changes: 10 additions & 13 deletions babel/localedata.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import threading
from collections import abc
from collections.abc import Iterator, Mapping, MutableMapping
from functools import lru_cache
from itertools import chain
from typing import Any

Expand Down Expand Up @@ -74,28 +75,24 @@ def exists(name: str) -> bool:
return True if file_found else bool(normalize_locale(name))


@lru_cache(maxsize=None)
def locale_identifiers() -> list[str]:
"""Return a list of all locale identifiers for which locale data is
available.
This data is cached after the first invocation in `locale_identifiers.cache`.
Removing the `locale_identifiers.cache` attribute or setting it to `None`
will cause this function to re-read the list from disk.
This data is cached after the first invocation.
You can clear the cache by calling `locale_identifiers.cache_clear()`.
.. versionadded:: 0.8.1
:return: a list of locale identifiers (strings)
"""
data = getattr(locale_identifiers, 'cache', None)
if data is None:
locale_identifiers.cache = data = [
stem
for stem, extension in
(os.path.splitext(filename) for filename in os.listdir(_dirname))
if extension == '.dat' and stem != 'root'
]
return data
return [
stem
for stem, extension in
(os.path.splitext(filename) for filename in os.listdir(_dirname))
if extension == '.dat' and stem != 'root'
]


def load(name: os.PathLike[str] | str, merge_inherited: bool = True) -> dict[str, Any]:
Expand Down
13 changes: 5 additions & 8 deletions tests/test_localedata.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,15 @@ def listdir_spy(*args):
rv = original_listdir(*args)
listdir_calls.append((args, rv))
return rv
monkeypatch.setattr(localedata.os, 'listdir', listdir_spy)

# In case we've already run some tests...
if hasattr(localedata.locale_identifiers, 'cache'):
del localedata.locale_identifiers.cache

monkeypatch.setattr(localedata.os, 'listdir', listdir_spy)
localedata.locale_identifiers.cache_clear()
assert not listdir_calls
assert localedata.locale_identifiers()
l = localedata.locale_identifiers()
assert len(listdir_calls) == 1
assert localedata.locale_identifiers() is localedata.locale_identifiers.cache
assert localedata.locale_identifiers() is l
assert len(listdir_calls) == 1
localedata.locale_identifiers.cache = None
localedata.locale_identifiers.cache_clear()
assert localedata.locale_identifiers()
assert len(listdir_calls) == 2

Expand Down

0 comments on commit 08af5e2

Please sign in to comment.