[Python-checkins] cpython (merge 3.5 -> 3.6): Issue #28385: An error message when non-empty format spec is passed to

serhiy.storchaka python-checkins at python.org
Sun Oct 30 13:38:44 EDT 2016


https://hg.python.org/cpython/rev/0a985f7c6731
changeset:   104829:0a985f7c6731
branch:      3.6
parent:      104826:f1abc92a756a
parent:      104828:92cae79fa5d9
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sun Oct 30 19:37:46 2016 +0200
summary:
  Issue #28385: An error message when non-empty format spec is passed to
object.__format__ now contains the name of actual type.

files:
  Lib/test/test_builtin.py |  24 ++++++++++------------
  Lib/test/test_bytes.py   |   9 ++++++++
  Objects/typeobject.c     |  30 +++++++++------------------
  3 files changed, 30 insertions(+), 33 deletions(-)


diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -11,6 +11,7 @@
 import pickle
 import platform
 import random
+import re
 import sys
 import traceback
 import types
@@ -1447,21 +1448,14 @@
 
         # --------------------------------------------------------------------
         # Issue #7994: object.__format__ with a non-empty format string is
-        #  deprecated
-        def test_deprecated_format_string(obj, fmt_str, should_raise):
-            if should_raise:
-                self.assertRaises(TypeError, format, obj, fmt_str)
-            else:
-                format(obj, fmt_str)
-
-        fmt_strs = ['', 's']
-
+        # disallowed
         class A:
             def __format__(self, fmt_str):
                 return format('', fmt_str)
 
-        for fmt_str in fmt_strs:
-            test_deprecated_format_string(A(), fmt_str, False)
+        self.assertEqual(format(A()), '')
+        self.assertEqual(format(A(), ''), '')
+        self.assertEqual(format(A(), 's'), '')
 
         class B:
             pass
@@ -1470,8 +1464,12 @@
             pass
 
         for cls in [object, B, C]:
-            for fmt_str in fmt_strs:
-                test_deprecated_format_string(cls(), fmt_str, len(fmt_str) != 0)
+            obj = cls()
+            self.assertEqual(format(obj), str(obj))
+            self.assertEqual(format(obj, ''), str(obj))
+            with self.assertRaisesRegex(TypeError,
+                                        r'\b%s\b' % re.escape(cls.__name__)):
+                format(obj, 's')
         # --------------------------------------------------------------------
 
         # make sure we can take a subclass of str as a format spec
diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py
--- a/Lib/test/test_bytes.py
+++ b/Lib/test/test_bytes.py
@@ -1416,6 +1416,15 @@
             self.assertEqual(f(b"'"), '''b"'"''') # '''
             self.assertEqual(f(b"'\""), r"""b'\'"'""") # '
 
+    @check_bytes_warnings
+    def test_format(self):
+        for b in b'abc', bytearray(b'abc'):
+            self.assertEqual(format(b), str(b))
+            self.assertEqual(format(b, ''), str(b))
+            with self.assertRaisesRegex(TypeError,
+                                        r'\b%s\b' % re.escape(type(b).__name__)):
+                format(b, 's')
+
     def test_compare_bytes_to_bytearray(self):
         self.assertEqual(b"abc" == bytes(b"abc"), True)
         self.assertEqual(b"ab" != bytes(b"abc"), True)
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -4392,13 +4392,6 @@
 "The default implementation does nothing. It may be\n"
 "overridden to extend subclasses.\n");
 
-/*
-   from PEP 3101, this code implements:
-
-   class object:
-       def __format__(self, format_spec):
-           return format(str(self), format_spec)
-*/
 static PyObject *
 object_format(PyObject *self, PyObject *args)
 {
@@ -4409,22 +4402,19 @@
     if (!PyArg_ParseTuple(args, "U:__format__", &format_spec))
         return NULL;
 
+    /* Issue 7994: If we're converting to a string, we
+       should reject format specifications */
+    if (PyUnicode_GET_LENGTH(format_spec) > 0) {
+        PyErr_Format(PyExc_TypeError,
+                     "unsupported format string passed to %.200s.__format__",
+                     self->ob_type->tp_name);
+        return NULL;
+    }
     self_as_str = PyObject_Str(self);
     if (self_as_str != NULL) {
-        /* Issue 7994: If we're converting to a string, we
-           should reject format specifications */
-        if (PyUnicode_GET_LENGTH(format_spec) > 0) {
-            PyErr_SetString(PyExc_TypeError,
-               "non-empty format string passed to object.__format__");
-            goto done;
-        }
-
         result = PyObject_Format(self_as_str, format_spec);
-    }
-
-done:
-    Py_XDECREF(self_as_str);
-
+        Py_DECREF(self_as_str);
+    }
     return result;
 }
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list