Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
c7217d7c
Commit
c7217d7c
authored
Dec 03, 2015
by
Serhiy Storchaka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #6478: _strptime's regexp cache now is reset after changing timezone
with time.tzset().
parent
7aa69086
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
50 additions
and
14 deletions
+50
-14
Lib/_strptime.py
Lib/_strptime.py
+14
-7
Lib/test/test_strptime.py
Lib/test/test_strptime.py
+33
-7
Misc/NEWS
Misc/NEWS
+3
-0
No files found.
Lib/_strptime.py
View file @
c7217d7c
...
...
@@ -77,6 +77,8 @@ class LocaleTime(object):
self
.
__calc_date_time
()
if
_getlang
()
!=
self
.
lang
:
raise
ValueError
(
"locale changed during initialization"
)
if
time
.
tzname
!=
self
.
tzname
or
time
.
daylight
!=
self
.
daylight
:
raise
ValueError
(
"timezone changed during initialization"
)
def
__pad
(
self
,
seq
,
front
):
# Add '' to seq to either the front (is True), else the back.
...
...
@@ -161,15 +163,17 @@ class LocaleTime(object):
def
__calc_timezone
(
self
):
# Set self.timezone by using time.tzname.
# Do not worry about possibility of time.tzname[0] == timetzname[1]
# and time.daylight; handle that in strptime
.
# Do not worry about possibility of time.tzname[0] == time
.
tzname[1]
# and time.daylight; handle that in strptime.
try
:
time
.
tzset
()
except
AttributeError
:
pass
no_saving
=
frozenset
([
"utc"
,
"gmt"
,
time
.
tzname
[
0
].
lower
()])
if
time
.
daylight
:
has_saving
=
frozenset
([
time
.
tzname
[
1
].
lower
()])
self
.
tzname
=
time
.
tzname
self
.
daylight
=
time
.
daylight
no_saving
=
frozenset
([
"utc"
,
"gmt"
,
self
.
tzname
[
0
].
lower
()])
if
self
.
daylight
:
has_saving
=
frozenset
([
self
.
tzname
[
1
].
lower
()])
else
:
has_saving
=
frozenset
()
self
.
timezone
=
(
no_saving
,
has_saving
)
...
...
@@ -308,12 +312,15 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
global _TimeRE_cache, _regex_cache
with _cache_lock:
if _getlang() != _TimeRE_cache.locale_time.lang:
locale_time = _TimeRE_cache.locale_time
if (_getlang() != locale_time.lang or
time.tzname != locale_time.tzname or
time.daylight != locale_time.daylight):
_TimeRE_cache = TimeRE()
_regex_cache.clear()
locale_time = _TimeRE_cache.locale_time
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:
...
...
Lib/test/test_strptime.py
View file @
c7217d7c
...
...
@@ -4,6 +4,7 @@ import unittest
import
time
import
locale
import
re
import
os
import
sys
from
test
import
support
from
datetime
import
date
as
datetime_date
...
...
@@ -324,9 +325,10 @@ class StrptimeTests(unittest.TestCase):
tz_name = time.tzname[0]
if tz_name.upper() in ("
UTC
", "
GMT
"):
self.skipTest('need non-UTC/GMT timezone')
try:
original_tzname = time.tzname
original_daylight = time.daylight
with support.swap_attr(time, 'tzname', (tz_name, tz_name)),
\
support.swap_attr(time, 'daylight', 1),
\
support.swap_attr(time, 'tzset', lambda: None):
time.tzname = (tz_name, tz_name)
time.daylight = 1
tz_value = _strptime._strptime_time(tz_name, "
%
Z
")[8]
...
...
@@ -334,9 +336,6 @@ class StrptimeTests(unittest.TestCase):
"
%
s
lead
to
a
timezone
value
of
%
s
instead
of
-
1
when
"
"
time
.
daylight
set
to
%
s
and
passing
in
%
s
" %
(time.tzname, tz_value, time.daylight, tz_name))
finally:
time.tzname = original_tzname
time.daylight = original_daylight
def test_date_time(self):
# Test %c directive
...
...
@@ -548,7 +547,7 @@ class CacheTests(unittest.TestCase):
_strptime._strptime_time("
10
", "
%
d
")
self.assertIsNot(locale_time_id, _strptime._TimeRE_cache.locale_time)
def test_TimeRE_recreation(self):
def test_TimeRE_recreation
_locale
(self):
# The TimeRE instance should be recreated upon changing the locale.
locale_info = locale.getlocale(locale.LC_TIME)
try:
...
...
@@ -577,6 +576,33 @@ class CacheTests(unittest.TestCase):
finally:
locale.setlocale(locale.LC_TIME, locale_info)
@support.run_with_tz('STD-1DST')
def test_TimeRE_recreation_timezone(self):
# The TimeRE instance should be recreated upon changing the timezone.
oldtzname = time.tzname
tm = _strptime._strptime_time(time.tzname[0], '%Z')
self.assertEqual(tm.tm_isdst, 0)
tm = _strptime._strptime_time(time.tzname[1], '%Z')
self.assertEqual(tm.tm_isdst, 1)
# Get id of current cache object.
first_time_re = _strptime._TimeRE_cache
# Change the timezone and force a recreation of the cache.
os.environ['TZ'] = 'EST+05EDT,M3.2.0,M11.1.0'
time.tzset()
tm = _strptime._strptime_time(time.tzname[0], '%Z')
self.assertEqual(tm.tm_isdst, 0)
tm = _strptime._strptime_time(time.tzname[1], '%Z')
self.assertEqual(tm.tm_isdst, 1)
# Get the new cache object's id.
second_time_re = _strptime._TimeRE_cache
# They should not be equal.
self.assertIsNot(first_time_re, second_time_re)
# Make sure old names no longer accepted.
with self.assertRaises(ValueError):
_strptime._strptime_time(oldtzname[0], '%Z')
with self.assertRaises(ValueError):
_strptime._strptime_time(oldtzname[1], '%Z')
def test_main():
support.run_unittest(
...
...
Misc/NEWS
View file @
c7217d7c
...
...
@@ -115,6 +115,9 @@ Core and Builtins
Library
-------
- Issue #6478: _strptime'
s
regexp
cache
now
is
reset
after
changing
timezone
with
time
.
tzset
().
-
Issue
#
25177
:
Fixed
problem
with
the
mean
of
very
small
and
very
large
numbers
.
As
a
side
effect
,
statistics
.
mean
and
statistics
.
variance
should
be
significantly
faster
.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment