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
b1f64e7d
Commit
b1f64e7d
authored
Dec 03, 2015
by
Serhiy Storchaka
Browse files
Options
Browse Files
Download
Plain Diff
Issue #6478: _strptime's regexp cache now is reset after changing timezone
with time.tzset().
parents
657257ed
c7217d7c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
50 additions
and
15 deletions
+50
-15
Lib/_strptime.py
Lib/_strptime.py
+14
-8
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 @
b1f64e7d
...
...
@@ -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
)
...
...
@@ -307,13 +311,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 @
b1f64e7d
...
...
@@ -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')
if __name__ == '__main__':
unittest.main()
Misc/NEWS
View file @
b1f64e7d
...
...
@@ -22,6 +22,9 @@ Core and Builtins
Library
-------
- Issue #6478: _strptime'
s
regexp
cache
now
is
reset
after
changing
timezone
with
time
.
tzset
().
-
Issue
#
14285
:
When
executing
a
package
with
the
"python -m package"
option
,
and
package
initialization
fails
,
a
proper
traceback
is
now
reported
.
The
"runpy"
module
now
lets
exceptions
from
package
initialization
pass
back
to
...
...
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