]> granicus.if.org Git - python/commitdiff
Make sure time.strptime only accepts strings (and document the fact like
authorBrett Cannon <bcannon@gmail.com>
Mon, 30 Mar 2009 21:30:26 +0000 (21:30 +0000)
committerBrett Cannon <bcannon@gmail.com>
Mon, 30 Mar 2009 21:30:26 +0000 (21:30 +0000)
strftime). Already didn't accept bytes but make the check earlier. This also
lifts the limitation of requiring ASCII.

Closes issue #5236. Thanks Tennessee Leeuwenburg.

Doc/library/time.rst
Lib/_strptime.py
Lib/test/test_time.py
Misc/ACKS
Misc/NEWS

index 46d972a3f0e7cea7f4bb45440c238ce584f6a394..cdc623d60d1efdc91421d18448fe2a1353fd9bd9 100644 (file)
@@ -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:
 
index 896c7986c4e1911d7e4e4555b18d15d9d73cfa12..9ff29bce8f7678c7ba3ac3b5f6f03ae340cd1c99 100644 (file)
@@ -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()
index 4c89f03bab31f8bf222648b90898cd415bb6d2e6..c2dfaca968ced6b1625386f207ac9cb2ecca2c32 100644 (file)
@@ -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)
index 85bc8a1279411de8009403d4a9aa43fc1dd849ef..85a443bba7d4dead46cb755a3bfc2028d201da4f 100644 (file)
--- 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
index f0dafcb8caf12f33f9b95a4f301b929a1fa18c31..f2888be1f3b1191ed7b4ca452b3da88658baacb3 100644 (file)
--- 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.