[Python-checkins] bpo-35066: _dateime.datetime.strftime copies trailing '%' (GH-10692)

Victor Stinner webhook-mailer at python.org
Mon Jan 14 05:23:49 EST 2019


https://github.com/python/cpython/commit/454b3d4ea246e8751534e105548d141ed7b0b032
commit: 454b3d4ea246e8751534e105548d141ed7b0b032
branch: master
author: MichaelSaah <mike.saah at gmail.com>
committer: Victor Stinner <vstinner at redhat.com>
date: 2019-01-14T11:23:39+01:00
summary:

bpo-35066: _dateime.datetime.strftime copies trailing '%' (GH-10692)

Previously, calling the strftime() method on a datetime object with a
trailing '%' in the format string would result in an exception. However,
this only occured when the datetime C module was being used; the python
implementation did not match this behavior. Datetime is now PEP-399
compliant, and will not throw an exception on a trailing '%'.

files:
A Misc/NEWS.d/next/Library/2018-11-29-09-38-40.bpo-35066.Nwej2s.rst
M Lib/test/datetimetester.py
M Modules/_datetimemodule.c

diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py
index 2f838c445555..d729c7efd52f 100644
--- a/Lib/test/datetimetester.py
+++ b/Lib/test/datetimetester.py
@@ -1351,6 +1351,17 @@ def test_strftime(self):
         #check that this standard extension works
         t.strftime("%f")
 
+    def test_strftime_trailing_percent(self):
+        # bpo-35066: make sure trailing '%' doesn't cause
+        # datetime's strftime to complain
+        t = self.theclass(2005, 3, 2)
+        try:
+            _time.strftime('%')
+        except ValueError:
+            self.skipTest('time module does not support trailing %')
+        self.assertEqual(t.strftime('%'), '%')
+        self.assertEqual(t.strftime("m:%m d:%d y:%y %"), "m:03 d:02 y:05 %")
+
     def test_format(self):
         dt = self.theclass(2007, 9, 10)
         self.assertEqual(dt.__format__(''), str(dt))
diff --git a/Misc/NEWS.d/next/Library/2018-11-29-09-38-40.bpo-35066.Nwej2s.rst b/Misc/NEWS.d/next/Library/2018-11-29-09-38-40.bpo-35066.Nwej2s.rst
new file mode 100644
index 000000000000..b0c39bd86383
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-11-29-09-38-40.bpo-35066.Nwej2s.rst
@@ -0,0 +1,5 @@
+Previously, calling the strftime() method on a datetime object with a
+trailing '%' in the format string would result in an exception. However,
+this only occured when the datetime C module was being used; the python
+implementation did not match this behavior. Datetime is now PEP-399
+compliant, and will not throw an exception on a trailing '%'.
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index 16c7bffda8f6..7997758908bb 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -1528,10 +1528,13 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
             ntoappend = 1;
         }
         else if ((ch = *pin++) == '\0') {
-            /* There's a lone trailing %; doesn't make sense. */
-            PyErr_SetString(PyExc_ValueError, "strftime format "
-                            "ends with raw %");
-            goto Done;
+        /* Null byte follows %, copy only '%'. 
+         * 
+         * Back the pin up one char so that we catch the null check
+         * the next time through the loop.*/
+            pin--;
+            ptoappend = pin - 1;
+            ntoappend = 1;
         }
         /* A % has been seen and ch is the character after it. */
         else if (ch == 'z') {
@@ -1616,7 +1619,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
         usednew += ntoappend;
         assert(usednew <= totalnew);
     }  /* end while() */
-
+    
     if (_PyBytes_Resize(&newfmt, usednew) < 0)
         goto Done;
     {



More information about the Python-checkins mailing list