]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
Cache locale_identifiers()
authorAarni Koskela <akx@iki.fi>
Mon, 27 May 2019 07:50:41 +0000 (10:50 +0300)
committerAarni Koskela <akx@iki.fi>
Mon, 27 May 2019 08:14:09 +0000 (11:14 +0300)
Fixes #620

babel/localedata.py
tests/test_localedata.py

index 2a8c4423d4be1ca3c4ac4e6f621a383e3e53d2f6..03381e2df046e2d7bac4a58d67a749cd130abf88 100644 (file)
@@ -57,13 +57,24 @@ def locale_identifiers():
     """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.
+
     .. versionadded:: 0.8.1
 
     :return: a list of locale identifiers (strings)
     """
-    return [stem for stem, extension in [
-        os.path.splitext(filename) for filename in os.listdir(_dirname)
-    ] if extension == '.dat' and stem != 'root']
+    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
 
 
 def load(name, merge_inherited=True):
index dceb984bea31187c965f2083f9df8b4e65da8ce6..bffe7633fba744ecb3996471e41e44f044661a08 100644 (file)
@@ -17,6 +17,7 @@ from operator import methodcaller
 
 from babel import localedata
 
+
 class MergeResolveTestCase(unittest.TestCase):
 
     def test_merge_items(self):
@@ -78,6 +79,7 @@ def test_locale_identification():
     for l in localedata.locale_identifiers():
         assert localedata.exists(l)
 
+
 def test_unique_ids():
     # Check all locale IDs are uniques.
     all_ids = localedata.locale_identifiers()
@@ -93,6 +95,7 @@ def test_mixedcased_locale():
             methodcaller(random.choice(['lower', 'upper']))(c) for c in l])
         assert localedata.exists(locale_id)
 
+
 def test_locale_argument_acceptance():
     # Testing None input.
     normalized_locale = localedata.normalize_locale(None)
@@ -105,3 +108,26 @@ def test_locale_argument_acceptance():
     assert normalized_locale is None
     locale_exist = localedata.exists(['en_us', None])
     assert locale_exist == False
+
+
+def test_locale_identifiers_cache(monkeypatch):
+    original_listdir = localedata.os.listdir
+    listdir_calls = []
+    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
+
+    assert not listdir_calls
+    assert localedata.locale_identifiers()
+    assert len(listdir_calls) == 1
+    assert localedata.locale_identifiers() is localedata.locale_identifiers.cache
+    assert len(listdir_calls) == 1
+    localedata.locale_identifiers.cache = None
+    assert localedata.locale_identifiers()
+    assert len(listdir_calls) == 2