summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/time.rst14
-rw-r--r--Lib/_strptime.py9
-rw-r--r--Lib/test/test_time.py5
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS3
5 files changed, 25 insertions, 7 deletions
diff --git a/Doc/library/time.rst b/Doc/library/time.rst
index 46d972a..cdc623d 100644
--- a/Doc/library/time.rst
+++ b/Doc/library/time.rst
@@ -358,15 +358,17 @@ The module defines the following functions and data items:
.. function:: strptime(string[, format])
- Parse a string representing a time according to a format. The return value is
- a :class:`struct_time` as returned by :func:`gmtime` or :func:`localtime`.
+ Parse a string representing a time according to a format. The return value
+ is a :class:`struct_time` as returned by :func:`gmtime` or
+ :func:`localtime`.
The *format* parameter uses the same directives as those used by
:func:`strftime`; it defaults to ``"%a %b %d %H:%M:%S %Y"`` which matches the
- formatting returned by :func:`ctime`. If *string* cannot be parsed according to
- *format*, or if it has excess data after parsing, :exc:`ValueError` is raised.
- The default values used to fill in any missing data when more accurate values
- cannot be inferred are ``(1900, 1, 1, 0, 0, 0, 0, 1, -1)``.
+ formatting returned by :func:`ctime`. If *string* cannot be parsed according
+ to *format*, or if it has excess data after parsing, :exc:`ValueError` is
+ raised. The default values used to fill in any missing data when more
+ accurate values cannot be inferred are ``(1900, 1, 1, 0, 0, 0, 0, 1, -1)``.
+ Both *string* and *format* must be strings.
For example:
diff --git a/Lib/_strptime.py b/Lib/_strptime.py
index 896c798..9ff29bc 100644
--- a/Lib/_strptime.py
+++ b/Lib/_strptime.py
@@ -262,7 +262,7 @@ class TimeRE(dict):
def compile(self, format):
"""Return a compiled re object for the format string."""
- return re_compile(self.pattern(format), IGNORECASE | ASCII)
+ return re_compile(self.pattern(format), IGNORECASE)
_cache_lock = _thread_allocate_lock()
# DO NOT modify _TimeRE_cache or _regex_cache without acquiring the cache lock
@@ -294,8 +294,15 @@ def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon):
def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
"""Return a time struct based on the input string and the format string."""
+
+ for index, arg in enumerate([data_string, format]):
+ if not isinstance(arg, str):
+ msg = "strptime() argument {} must be str, not {}"
+ raise TypeError(msg.format(arg, index))
+
global _TimeRE_cache, _regex_cache
with _cache_lock:
+
if _getlang() != _TimeRE_cache.locale_time.lang:
_TimeRE_cache = TimeRE()
_regex_cache.clear()
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
index 4c89f03..c2dfaca 100644
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -116,6 +116,11 @@ class TimeTestCase(unittest.TestCase):
self.fail("conversion specifier %r failed with '%s' input." %
(format, strf_output))
+ def test_strptime_bytes(self):
+ # Make sure only strings are accepted as arguments to strptime.
+ self.assertRaises(TypeError, time.strptime, b'2009', "%Y")
+ self.assertRaises(TypeError, time.strptime, '2009', b'%Y')
+
def test_asctime(self):
time.asctime(time.gmtime(self.t))
self.assertRaises(TypeError, time.asctime, 0)
diff --git a/Misc/ACKS b/Misc/ACKS
index 85bc8a1..85a443b 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -411,6 +411,7 @@ John J. Lee
Inyeol Lee
Thomas Lee
Christopher Lee
+Tennessee Leeuwenburg
Luc Lefebvre
Kip Lehman
Joerg Lehmann
diff --git a/Misc/NEWS b/Misc/NEWS
index f0dafcb..f2888be 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -43,6 +43,9 @@ Core and Builtins
Library
-------
+- Issue #5236: Change time.strptime() to only take strings. Didn't work with
+ bytes already but the failure was non-obvious.
+
- Issue #5177: Multiprocessing's SocketListener class now uses
socket.SO_REUSEADDR on all connections so that the user no longer needs
to wait 120 seconds for the socket to expire.