Backport fix for r54646-7: properly clear locale cache in time.strptime when
the locale changes between calls.
This commit is contained in:
parent
a801b6a1fd
commit
daa2e58104
|
@ -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:
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue