[Python-checkins] cpython: Issue19995: issue deprecation warning for non-integer values to %c, %o, %x, %X

ethan.furman python-checkins at python.org
Sun Jan 12 08:21:03 CET 2014


http://hg.python.org/cpython/rev/22e55bd5583c
changeset:   88421:22e55bd5583c
user:        Ethan Furman <ethan at stoneleaf.us>
date:        Sat Jan 11 23:20:58 2014 -0800
summary:
  Issue19995: issue deprecation warning for non-integer values to %c, %o, %x, %X

files:
  Lib/test/test_format.py  |   5 ++++
  Lib/test/test_unicode.py |  20 ++++++++++++++----
  Misc/NEWS                |   4 +-
  Objects/unicodeobject.c  |  29 ++++++++++++++++++++++++++-
  4 files changed, 49 insertions(+), 9 deletions(-)


diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py
--- a/Lib/test/test_format.py
+++ b/Lib/test/test_format.py
@@ -142,6 +142,7 @@
         testformat("%#+027.23X", big, "+0X0001234567890ABCDEF12345")
         # same, except no 0 flag
         testformat("%#+27.23X", big, " +0X001234567890ABCDEF12345")
+        testformat("%x", float(big), "123456_______________", 6)
         big = 0o12345670123456701234567012345670  # 32 octal digits
         testformat("%o", big, "12345670123456701234567012345670")
         testformat("%o", -big, "-12345670123456701234567012345670")
@@ -181,6 +182,7 @@
         testformat("%034.33o", big, "0012345670123456701234567012345670")
         # base marker shouldn't change that
         testformat("%0#34.33o", big, "0o012345670123456701234567012345670")
+        testformat("%o", float(big), "123456__________________________", 6)
         # Some small ints, in both Python int and flavors).
         testformat("%d", 42, "42")
         testformat("%d", -42, "-42")
@@ -191,6 +193,7 @@
         testformat("%#x", 1, "0x1")
         testformat("%#X", 1, "0X1")
         testformat("%#X", 1, "0X1")
+        testformat("%#x", 1.0, "0x1")
         testformat("%#o", 1, "0o1")
         testformat("%#o", 1, "0o1")
         testformat("%#o", 0, "0o0")
@@ -207,10 +210,12 @@
         testformat("%x", -0x42, "-42")
         testformat("%x", 0x42, "42")
         testformat("%x", -0x42, "-42")
+        testformat("%x", float(0x42), "42")
         testformat("%o", 0o42, "42")
         testformat("%o", -0o42, "-42")
         testformat("%o", 0o42, "42")
         testformat("%o", -0o42, "-42")
+        testformat("%o", float(0o42), "42")
         testformat("%r", "\u0378", "'\\u0378'")  # non printable
         testformat("%a", "\u0378", "'\\u0378'")  # non printable
         testformat("%r", "\u0374", "'\u0374'")   # printable
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -1139,6 +1139,13 @@
                 self.value = float(value)
             def __int__(self):
                 return int(self.value)
+        def check_depr(modifier, value):
+            with support.check_warnings(
+                    ("", DeprecationWarning),
+                    quiet=False,
+                    ):
+                warnings.simplefilter('always')
+                modifier % value
         pi = PsuedoFloat(3.1415)
         letter_m = PsuedoInt(109)
         self.assertEqual('%x' % 42, '2a')
@@ -1149,11 +1156,14 @@
         self.assertEqual('%X' % letter_m, '6D')
         self.assertEqual('%o' % letter_m, '155')
         self.assertEqual('%c' % letter_m, 'm')
-        self.assertRaises(TypeError, '%x'.__mod__, pi)
-        self.assertRaises(TypeError, '%x'.__mod__, 3.14)
-        self.assertRaises(TypeError, '%X'.__mod__, 2.11)
-        self.assertRaises(TypeError, '%o'.__mod__, 1.79)
-        self.assertRaises(TypeError, '%c'.__mod__, pi)
+        for mod, value in (
+                ('%x', pi),
+                ('%x', 3.14),
+                ('%X', 2.11),
+                ('%o', 1.79),
+                ('%c', pi),
+                ):
+            check_depr(mod, value)
 
     def test_formatting_with_enum(self):
         # issue18780
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -117,8 +117,8 @@
 - Issue #19969: PyBytes_FromFormatV() now raises an OverflowError if "%c"
   argument is not in range [0; 255].
 
-- Issue #19995: %c, %o, %x, and %X now raise TypeError on non-integer input;
-  reworded docs to clarify that an integer type should define both __int__
+- Issue #19995: %c, %o, %x, and %X now issue a DeprecationWarning on non-integer
+  input; reworded docs to clarify that an integer type should define both __int__
   and __index__.
 
 - Issue #19787: PyThread_set_key_value() now always set the value. In Python
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -14004,11 +14004,24 @@
     if (!PyNumber_Check(v))
         goto wrongtype;
 
+    /* make sure number is a type of integer */
+    /* if not, issue depracation warning for now */
     if (!PyLong_Check(v)) {
         if (type == 'o' || type == 'x' || type == 'X') {
             iobj = PyNumber_Index(v);
             if (iobj == NULL) {
-                return -1;
+                PyErr_Clear();
+                if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                                 "automatic int conversions have been deprecated",
+                                 1)) {
+                    return -1;
+                }
+                iobj = PyNumber_Long(v);
+                if (iobj == NULL ) {
+                    if (PyErr_ExceptionMatches(PyExc_TypeError))
+                        goto wrongtype;
+                    return -1;
+                }
             }
         }
         else {
@@ -14090,10 +14103,22 @@
         PyObject *iobj;
         long x;
         /* make sure number is a type of integer */
+        /* if not, issue depracation warning for now */
         if (!PyLong_Check(v)) {
             iobj = PyNumber_Index(v);
             if (iobj == NULL) {
-                goto onError;
+                PyErr_Clear();
+                if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                                 "automatic int conversions have been deprecated",
+                                 1)) {
+                    return -1;
+                }
+                iobj = PyNumber_Long(v);
+                if (iobj == NULL ) {
+                    if (PyErr_ExceptionMatches(PyExc_TypeError))
+                        goto onError;
+                    return -1;
+                }
             }
             v = iobj;
             Py_DECREF(iobj);

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


More information about the Python-checkins mailing list