]> granicus.if.org Git - python/commitdiff
Backport fix for r54646-7: properly clear locale cache in time.strptime when
authorBrett Cannon <bcannon@gmail.com>
Fri, 27 Apr 2007 23:17:43 +0000 (23:17 +0000)
committerBrett Cannon <bcannon@gmail.com>
Fri, 27 Apr 2007 23:17:43 +0000 (23:17 +0000)
the locale changes between calls.

Lib/_strptime.py
Lib/test/test_strptime.py
Misc/NEWS

index ef010362163fd03a65d43796b3231693284ca392..476f9d8a36a0b26d06851c5720bd9e8c75552151 100644 (file)
@@ -299,17 +299,16 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
     global _TimeRE_cache, _regex_cache
     _cache_lock.acquire()
     try:
-        time_re = _TimeRE_cache
-        locale_time = time_re.locale_time
-        if _getlang() != locale_time.lang:
+        if _getlang() != _TimeRE_cache.locale_time.lang:
             _TimeRE_cache = TimeRE()
-            _regex_cache = {}
+            _regex_cache.clear()
         if len(_regex_cache) > _CACHE_MAX_SIZE:
             _regex_cache.clear()
+        locale_time = _TimeRE_cache.locale_time
         format_regex = _regex_cache.get(format)
         if not format_regex:
             try:
-                format_regex = time_re.compile(format)
+                format_regex = _TimeRE_cache.compile(format)
             # KeyError raised when a bad format is found; can be specified as
             # \\, in which case it was a stray % but with a space after it
             except KeyError, err:
index 56e1ab87aa2840ff65214200a0753d1a6b453df7..f4747521bff6c08f3407f11f535e386ed8c2aa5f 100644 (file)
@@ -505,6 +505,35 @@ class CacheTests(unittest.TestCase):
         self.failIfEqual(locale_time_id,
                          id(_strptime._TimeRE_cache.locale_time))
 
+    def test_TimeRE_recreation(self):
+        # The TimeRE instance should be recreated upon changing the locale.
+        locale_info = locale.getlocale(locale.LC_TIME)
+        try:
+            locale.setlocale(locale.LC_TIME, ('en_US', 'UTF8'))
+        except locale.Error:
+            return
+        try:
+            _strptime.strptime('10', '%d')
+            # Get id of current cache object.
+            first_time_re_id = id(_strptime._TimeRE_cache)
+            try:
+                # Change the locale and force a recreation of the cache.
+                locale.setlocale(locale.LC_TIME, ('de_DE', 'UTF8'))
+                _strptime.strptime('10', '%d')
+                # Get the new cache object's id.
+                second_time_re_id = id(_strptime._TimeRE_cache)
+                # They should not be equal.
+                self.failIfEqual(first_time_re_id, second_time_re_id)
+            # Possible test locale is not supported while initial locale is.
+            # If this is the case just suppress the exception and fall-through
+            # to the reseting to the original locale.
+            except locale.Error:
+                pass
+        # Make sure we don't trample on the locale setting once we leave the
+        # test.
+        finally:
+            locale.setlocale(locale.LC_TIME, locale_info)
+
 
 def test_main():
     test_support.run_unittest(
index bb8385f811fa8525899f12593d8dc2328fe0f3b7..65e176ed83e319c2e84fad8aedd5bf3f47797428 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.5.2c1?
 Library
 -------
 
+- Bug #1290505: Properly clear time.strptime's locale cache when the locale
+  changes between calls.  Backport of r54646 and r54647.
+
 - Bug #1706381: Specifying the SWIG option "-c++" in the setup.py file
   (as opposed to the command line) will now write file names ending in
   ".cpp" too.