Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5187a3b

Browse files
committed
Fix handling of bad locale setup where time.tzname[0] == time.tzname[1] and
time.daylight is true. Add an explicit test for this situation. Fixed some wording in docstrings.
1 parent 3081d59 commit 5187a3b

2 files changed

Lines changed: 39 additions & 10 deletions

File tree

Lib/_strptime.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ def __init__(self):
6464
locks to prevent changing the locale while locale-dependent code is
6565
running. The check here is done in case someone does not think about
6666
doing this.
67+
68+
Only other possible issue is if someone changed the timezone and did
69+
not call tz.tzset . That is an issue for the programmer, though,
70+
since changing the timezone is worthless without that call.
6771
6872
"""
6973
self.lang = _getlang()
@@ -155,6 +159,8 @@ def __calc_date_time(self):
155159

156160
def __calc_timezone(self):
157161
# Set self.timezone by using time.tzname.
162+
# Do not worry about possibility of time.tzname[0] == timetzname[1]
163+
# and time.daylight; handle that in strptime .
158164
try:
159165
time.tzset()
160166
except AttributeError:
@@ -237,7 +243,7 @@ def pattern(self, format):
237243
"""Return regex pattern for the format string.
238244
239245
Need to make sure that any characters that might be interpreted as
240-
regex syntax is escaped.
246+
regex syntax are escaped.
241247
242248
"""
243249
processed_format = ''
@@ -263,11 +269,11 @@ def compile(self, format):
263269
# DO NOT modify _TimeRE_cache or _regex_cache without acquiring the cache lock
264270
# first!
265271
_TimeRE_cache = TimeRE()
266-
_CACHE_MAX_SIZE = 5
272+
_CACHE_MAX_SIZE = 5 # Max number of regexes stored in _regex_cache
267273
_regex_cache = {}
268274

269275
def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
270-
"""Return a time struct based on the input data and the format string."""
276+
"""Return a time struct based on the input string and the format string."""
271277
global _TimeRE_cache
272278
_cache_lock.acquire()
273279
try:
@@ -355,14 +361,17 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
355361
# Since -1 is default value only need to worry about setting tz if
356362
# it can be something other than -1.
357363
found_zone = found_dict['Z'].lower()
358-
if locale_time.timezone[0] == locale_time.timezone[1] and \
359-
time.daylight:
360-
pass #Deals with bad locale setup where timezone info is
361-
# the same; first found on FreeBSD 4.4.
362-
else:
363-
for value, tz_values in enumerate(locale_time.timezone):
364-
if found_zone in tz_values:
364+
for value, tz_values in enumerate(locale_time.timezone):
365+
if found_zone in tz_values:
366+
# Deal with bad locale setup where timezone names are the
367+
# same and yet time.daylight is true; too ambiguous to
368+
# be able to tell what timezone has daylight savings
369+
if time.tzname[0] == time.tzname[1] and \
370+
time.daylight:
371+
break
372+
else:
365373
tz = value
374+
break
366375
# Cannot pre-calculate datetime_date() since can change in Julian
367376
#calculation and thus could have different value for the day of the week
368377
#calculation

Lib/test/test_strptime.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import locale
66
import re
77
import sets
8+
import sys
89
from test import test_support
910

1011
import _strptime
@@ -258,6 +259,9 @@ def test_timezone(self):
258259
self.failUnlessEqual(strp_output.tm_isdst, 0)
259260
strp_output = _strptime.strptime("GMT", "%Z")
260261
self.failUnlessEqual(strp_output.tm_isdst, 0)
262+
if sys.platform == "mac":
263+
# Timezones don't really work on MacOS9
264+
return
261265
time_tuple = time.localtime()
262266
strf_output = time.strftime("%Z") #UTC does not have a timezone
263267
strp_output = _strptime.strptime(strf_output, "%Z")
@@ -271,6 +275,22 @@ def test_timezone(self):
271275
"LocaleTime().timezone has duplicate values and "
272276
"time.daylight but timezone value not set to -1")
273277

278+
def test_bad_timezone(self):
279+
# Explicitly test possibility of bad timezone;
280+
# when time.tzname[0] == time.tzname[1] and time.daylight
281+
if sys.platform == "mac":
282+
return #MacOS9 has severely broken timezone support.
283+
try:
284+
original_tzname = time.tzname
285+
original_daylight = time.daylight
286+
time.tzname = ("PDT", "PDT")
287+
time.daylight = 1
288+
tz_value = _strptime.strptime("PDT", "%Z")[8]
289+
self.failUnlessEqual(tz_value, -1)
290+
finally:
291+
time.tzname = original_tzname
292+
time.daylight = original_daylight
293+
274294
def test_date_time(self):
275295
# Test %c directive
276296
for position in range(6):

0 commit comments

Comments
 (0)