diff -r 2f81f0e331f6 Lib/test/test_format.py --- a/Lib/test/test_format.py Sun Jan 05 06:50:30 2014 -0800 +++ b/Lib/test/test_format.py Fri Jan 10 19:45:25 2014 -0800 @@ -135,20 +135,21 @@ class FormatTest(unittest.TestCase): testformat("%#+.23X", big, "+0X001234567890ABCDEF12345") testformat("%#-+.23X", big, "+0X001234567890ABCDEF12345") testformat("%#-+26.23X", big, "+0X001234567890ABCDEF12345") testformat("%#-+27.23X", big, "+0X001234567890ABCDEF12345 ") testformat("%#+27.23X", big, " +0X001234567890ABCDEF12345") # next one gets two leading zeroes from precision, and another from the # 0 flag and the width 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") testformat("%5o", -big, "-12345670123456701234567012345670") testformat("%33o", -big, "-12345670123456701234567012345670") testformat("%34o", -big, " -12345670123456701234567012345670") testformat("%-34o", -big, "-12345670123456701234567012345670 ") testformat("%034o", -big, "-012345670123456701234567012345670") testformat("%-034o", -big, "-12345670123456701234567012345670 ") testformat("%036o", -big, "-00012345670123456701234567012345670") @@ -174,50 +175,54 @@ class FormatTest(unittest.TestCase): # next one gets one leading zero from precision testformat("%.33o", big, "012345670123456701234567012345670") # base marker shouldn't change that, since "0" is redundant testformat("%#.33o", big, "0o012345670123456701234567012345670") # but reduce precision, and base marker should add a zero testformat("%#.32o", big, "0o12345670123456701234567012345670") # one leading zero from precision, and another from "0" flag & width 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") testformat("%d", 42, "42") testformat("%d", -42, "-42") testformat("%d", 42.0, "42") testformat("%#x", 1, "0x1") 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") testformat("%#o", 0, "0o0") testformat("%o", 0, "0") testformat("%o", 0, "0") testformat("%d", 0, "0") testformat("%d", 0, "0") testformat("%#x", 0, "0x0") testformat("%#x", 0, "0x0") testformat("%#X", 0, "0X0") testformat("%#X", 0, "0X0") testformat("%x", 0x42, "42") 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 testformat("%a", "\u0374", "'\\u0374'") # printable # alternate float formatting testformat('%g', 1.1, '1.1') testformat('%#g', 1.1, '1.10000') # Test exception for unknown format characters diff -r 2f81f0e331f6 Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py Sun Jan 05 06:50:30 2014 -0800 +++ b/Lib/test/test_unicode.py Fri Jan 10 19:45:25 2014 -0800 @@ -1142,25 +1142,28 @@ class UnicodeTest(string_tests.CommonTes pi = PsuedoFloat(3.1415) letter_m = PsuedoInt(109) self.assertEquals('%x' % 42, '2a') self.assertEquals('%X' % 15, 'F') self.assertEquals('%o' % 9, '11') self.assertEquals('%c' % 109, 'm') self.assertEquals('%x' % letter_m, '6d') self.assertEquals('%X' % letter_m, '6D') self.assertEquals('%o' % letter_m, '155') self.assertEquals('%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) + with support.check_warnings( + ("automatic int conversions have been deprecated", DeprecationWarning) + ): + exec("'%x' % pi") + exec("'%x' % 3.14") + exec("'%X' % 2.11") + exec("'%o' % 1.79") + exec("'%c' % pi") def test_formatting_with_enum(self): # issue18780 import enum class Float(float, enum.Enum): PI = 3.1415926 class Int(enum.IntEnum): IDES = 15 class Str(str, enum.Enum): ABC = 'abc' diff -r 2f81f0e331f6 Misc/NEWS --- a/Misc/NEWS Sun Jan 05 06:50:30 2014 -0800 +++ b/Misc/NEWS Fri Jan 10 19:45:25 2014 -0800 @@ -11,22 +11,22 @@ Core and Builtins ----------------- - Issue #17432: Drop UCS2 from names of Unicode functions in python3.def. - Issue #19526: Exclude all new API from the stable ABI. Exceptions can be made if a need is demonstrated. - 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 3.3, the function did nothing if the key already exists (if the current value is a non-NULL pointer). - Issue #14432: Remove the thread state field from the frame structure. Fix a crash when a generator is created in a C thread that is destroyed while the generator is still used. The issue was that a generator contains a frame, and the frame kept a reference to the Python state of the destroyed C thread. The diff -r 2f81f0e331f6 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Sun Jan 05 06:50:30 2014 -0800 +++ b/Objects/unicodeobject.c Fri Jan 10 19:45:25 2014 -0800 @@ -13997,25 +13997,38 @@ mainformatlong(PyObject *v, struct unicode_format_arg_t *arg, PyObject **p_output, _PyUnicodeWriter *writer) { PyObject *iobj, *res; char type = (char)arg->ch; 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 { iobj = PyNumber_Long(v); if (iobj == NULL ) { if (PyErr_ExceptionMatches(PyExc_TypeError)) goto wrongtype; return -1; } } @@ -14083,24 +14096,36 @@ formatchar(PyObject *v) if (PyUnicode_Check(v)) { if (PyUnicode_GET_LENGTH(v) == 1) { return PyUnicode_READ_CHAR(v, 0); } goto onError; } else { 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); } /* Integer input truncated to a character */ x = PyLong_AsLong(v); if (x == -1 && PyErr_Occurred()) goto onError; if (x < 0 || x > MAX_UNICODE) {