1. Armin Rigo
  2. cpython-withatomic

Commits

Brett Cannon  committed b33c60f

Remove caching of TimeRE (and thus LocaleTime) instance. Error was being
caught when executing test_strptime, test_logging, and test_time in that order
when the testing of "%c" occured. Suspect the cache was not being recreated
(the test passed when test_logging was forced to re-establish the locale).

  • Participants
  • Parent commits 29f07ad
  • Branches legacy-trunk

Comments (0)

Files changed (2)

File Lib/_strptime.py

View file
 
 def _getlang():
     # Figure out what the current language is set to.
-    current_lang = locale.getlocale(locale.LC_TIME)[0]
-    if current_lang:
-        return current_lang
-    else:
-        current_lang = locale.getdefaultlocale()[0]
-        if current_lang:
-            return current_lang
-        else:
-            return ''
+    return locale.getlocale(locale.LC_TIME)
 
 class LocaleTime(object):
     """Stores and handles locale-specific information related to time.
 
+    This is not thread-safe!  Attributes are lazily calculated and no
+    precaution is taken to check to see if the locale information has changed
+    since the creation of the instance in use.
+
     ATTRIBUTES (all read-only after instance creation! Instance variables that
                 store the values have mangled names):
         f_weekday -- full weekday names (7-item list)
                 raise TypeError("timezone names must contain 2 items")
             else:
                 self.__timezone = self.__pad(timezone, False)
-        self.__lang = lang
+        if lang:
+            self.__lang = lang
+        else:
+            self.__lang = _getlang()
 
     def __pad(self, seq, front):
         # Add '' to seq to either front (is True), else the back.
     LC_time = property(__get_LC_time, __set_nothing,
         doc="Format string for locale's time representation ('%X' format)")
 
-    def __get_lang(self):
-        # Fetch self.lang.
-        if not self.__lang:
-            self.__calc_lang()
-        return self.__lang
-
-    lang = property(__get_lang, __set_nothing,
+    lang = property(lambda self: self.__lang, __set_nothing,
                     doc="Language used for instance")
 
     def __calc_weekday(self):
             time_zones.append(time.tzname[0])
         self.__timezone = self.__pad(time_zones, 0)
 
-    def __calc_lang(self):
-        # Set self.__lang by using __getlang().
-        self.__lang = _getlang()
-
-
 
 class TimeRE(dict):
     """Handle conversion from format directives to regexes."""
         """Return a compiled re object for the format string."""
         return re_compile(self.pattern(format), IGNORECASE)
 
-# Cached TimeRE; probably only need one instance ever so cache it for performance
-_locale_cache = TimeRE()
-# Cached regex objects; same reason as for TimeRE cache
-_regex_cache = dict()
 
 def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
     """Return a time struct based on the input data and the format string."""
-    global _locale_cache
-    global _regex_cache
-    locale_time = _locale_cache.locale_time
-    # If the language changes, caches are invalidated, so clear them
-    if locale_time.lang != _getlang():
-        _locale_cache = TimeRE()
-        _regex_cache.clear()
-    format_regex = _regex_cache.get(format)
-    if not format_regex:
-        # Limit regex cache size to prevent major bloating of the module;
-        # The value 5 is arbitrary
-        if len(_regex_cache) > 5:
-            _regex_cache.clear()
-        format_regex = _locale_cache.compile(format)
-        _regex_cache[format] = format_regex
+    time_re = TimeRE()
+    locale_time = time_re.locale_time
+    format_regex = time_re.compile(format)
     found = format_regex.match(data_string)
     if not found:
         raise ValueError("time data did not match format:  data=%s  fmt=%s" %

File Lib/test/test_strptime.py

View file
 
 import _strptime
 
+class getlang_Tests(unittest.TestCase):
+    """Test _getlang"""
+    def test_basic(self):
+        self.failUnlessEqual(_strptime._getlang(), locale.getlocale(locale.LC_TIME))
+
 class LocaleTime_Tests(unittest.TestCase):
     """Tests for _strptime.LocaleTime."""
 
                                     "empty strings")
 
     def test_lang(self):
-        # Make sure lang is set
-        self.failUnless(self.LT_ins.lang in (locale.getdefaultlocale()[0],
-                                             locale.getlocale(locale.LC_TIME)[0],
-                                             ''),
-                        "Setting of lang failed")
+        # Make sure lang is set to what _getlang() returns
+        # Assuming locale has not changed between now and when self.LT_ins was created
+        self.failUnlessEqual(self.LT_ins.lang, _strptime._getlang())
 
     def test_by_hand_input(self):
         # Test passed-in initialization value checks
         self.failUnless(result.tm_wday == self.time_tuple.tm_wday,
                         "Calculation of day of the week failed;"
                          "%s != %s" % (result.tm_wday, self.time_tuple.tm_wday))
-
 def test_main():
     test_support.run_unittest(
+        getlang_Tests,
         LocaleTime_Tests,
         TimeRETests,
         StrptimeTests,
         Strptime12AMPMTests,
         JulianTests,
-        CalculationTests
+        CalculationTests,
     )