Backport fix for r54646-7: properly clear locale cache in time.strptime when

the locale changes between calls.
This commit is contained in:
Brett Cannon 2007-04-27 23:17:43 +00:00
parent a801b6a1fd
commit daa2e58104
3 changed files with 36 additions and 5 deletions

View File

@ -299,17 +299,16 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
global _TimeRE_cache, _regex_cache global _TimeRE_cache, _regex_cache
_cache_lock.acquire() _cache_lock.acquire()
try: try:
time_re = _TimeRE_cache if _getlang() != _TimeRE_cache.locale_time.lang:
locale_time = time_re.locale_time
if _getlang() != locale_time.lang:
_TimeRE_cache = TimeRE() _TimeRE_cache = TimeRE()
_regex_cache = {} _regex_cache.clear()
if len(_regex_cache) > _CACHE_MAX_SIZE: if len(_regex_cache) > _CACHE_MAX_SIZE:
_regex_cache.clear() _regex_cache.clear()
locale_time = _TimeRE_cache.locale_time
format_regex = _regex_cache.get(format) format_regex = _regex_cache.get(format)
if not format_regex: if not format_regex:
try: 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 # 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 # \\, in which case it was a stray % but with a space after it
except KeyError, err: except KeyError, err:

View File

@ -505,6 +505,35 @@ class CacheTests(unittest.TestCase):
self.failIfEqual(locale_time_id, self.failIfEqual(locale_time_id,
id(_strptime._TimeRE_cache.locale_time)) 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(): def test_main():
test_support.run_unittest( test_support.run_unittest(

View File

@ -12,6 +12,9 @@ What's New in Python 2.5.2c1?
Library 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 - 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 (as opposed to the command line) will now write file names ending in
".cpp" too. ".cpp" too.