diff -r fd846837492d Doc/reference/datamodel.rst --- a/Doc/reference/datamodel.rst Mon Dec 30 09:33:46 2013 +0100 +++ b/Doc/reference/datamodel.rst Mon Dec 30 07:55:10 2013 -0800 @@ -2073,23 +2073,31 @@ left undefined. builtin: float builtin: round Called to implement the built-in functions :func:`complex`, :func:`int`, :func:`float` and :func:`round`. Should return a value of the appropriate type. .. method:: object.__index__(self) - Called to implement :func:`operator.index`. Also called whenever Python needs - an integer object (such as in slicing, or in the built-in :func:`bin`, - :func:`hex` and :func:`oct` functions). Must return an integer. + Called to implement :func:`operator.index`, and whenever Python needs to + losslessly convert the numeric object to an integer object (such as in + slicing, or in the built-in :func:`bin`, :func:`hex` and :func:`oct` + functions). Presence of this method indicates that the numeric object is + an integer type. Must return an integer. + + .. note:: + + When :meth:`__index__` is defined, :meth:`__int__` should also be defined, + and both shuld return the same value, in order to have a coherent integer + type class. .. _context-managers: With Statement Context Managers ------------------------------- A :dfn:`context manager` is an object that defines the runtime context to be established when executing a :keyword:`with` statement. The context manager handles the entry into, and the exit from, the desired runtime context for the diff -r fd846837492d Lib/tarfile.py --- a/Lib/tarfile.py Mon Dec 30 09:33:46 2013 +0100 +++ b/Lib/tarfile.py Mon Dec 30 07:55:10 2013 -0800 @@ -189,21 +189,21 @@ def itn(n, digits=8, format=DEFAULT_FORM """ # POSIX 1003.1-1988 requires numbers to be encoded as a string of # octal digits followed by a null-byte, this allows values up to # (8**(digits-1))-1. GNU tar allows storing numbers greater than # that if necessary. A leading 0o200 or 0o377 byte indicate this # particular encoding, the following digits-1 bytes are a big-endian # base-256 representation. This allows values up to (256**(digits-1))-1. # A 0o200 byte indicates a positive number, a 0o377 byte a negative # number. if 0 <= n < 8 ** (digits - 1): - s = bytes("%0*o" % (digits - 1, n), "ascii") + NUL + s = bytes("%0*o" % (digits - 1, int(n)), "ascii") + NUL elif format == GNU_FORMAT and -256 ** (digits - 1) <= n < 256 ** (digits - 1): if n >= 0: s = bytearray([0o200]) else: s = bytearray([0o377]) n = 256 ** digits + n for i in range(digits - 1): s.insert(1, n & 0o377) n >>= 8 diff -r fd846837492d Lib/test/test_format.py --- a/Lib/test/test_format.py Mon Dec 30 09:33:46 2013 +0100 +++ b/Lib/test/test_format.py Mon Dec 30 07:55:10 2013 -0800 @@ -135,21 +135,20 @@ 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") @@ -175,54 +174,50 @@ 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 fd846837492d Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py Mon Dec 30 09:33:46 2013 +0100 +++ b/Lib/test/test_unicode.py Mon Dec 30 07:55:10 2013 -0800 @@ -1119,20 +1119,49 @@ class UnicodeTest(string_tests.CommonTes INF = float('inf') self.assertEqual('%f' % NAN, 'nan') self.assertEqual('%F' % NAN, 'NAN') self.assertEqual('%f' % INF, 'inf') self.assertEqual('%F' % INF, 'INF') # PEP 393 self.assertEqual('%.1s' % "a\xe9\u20ac", 'a') self.assertEqual('%.2s' % "a\xe9\u20ac", 'a\xe9') + #issue 19995 + class PsuedoInt: + def __init__(self, value): + self.value = int(value) + def __int__(self): + return self.value + def __index__(self): + return self.value + class PsuedoFloat: + def __init__(self, value): + self.value = float(value) + def __int__(self): + return int(self.value) + 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) + 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' # Testing Unicode formatting strings... diff -r fd846837492d Misc/NEWS --- a/Misc/NEWS Mon Dec 30 09:33:46 2013 +0100 +++ b/Misc/NEWS Mon Dec 30 07:55:10 2013 -0800 @@ -6,20 +6,24 @@ What's New in Python 3.4.0 Beta 2? ================================== Release date: 2014-01-05 Core and Builtins ----------------- - 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__ + 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 crash occurs when a trace function is setup. diff -r fd846837492d Objects/unicodeobject.c --- a/Objects/unicodeobject.c Mon Dec 30 09:33:46 2013 +0100 +++ b/Objects/unicodeobject.c Mon Dec 30 07:55:10 2013 -0800 @@ -14008,42 +14008,50 @@ formatlong(PyObject *val, struct unicode Py_DECREF(result); result = unicode; } else if (len != PyUnicode_GET_LENGTH(result)) { if (PyUnicode_Resize(&result, len) < 0) Py_CLEAR(result); } return result; } -/* Format an integer. +/* Format an integer or a float as an integer. * Return 1 if the number has been formatted into the writer, * 0 if the number has been formatted into *p_output * -1 and raise an exception on error */ static int 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; if (!PyLong_Check(v)) { - iobj = PyNumber_Long(v); - if (iobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - goto wrongtype; - return -1; + if (type == 'o' || type == 'x' || type == 'X') { + iobj = PyNumber_Index(v); + if (iobj == NULL) { + return -1; + } + } + else { + iobj = PyNumber_Long(v); + if (iobj == NULL ) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + goto wrongtype; + return -1; + } } assert(PyLong_Check(iobj)); } else { iobj = v; Py_INCREF(iobj); } if (PyLong_CheckExact(v) && arg->width == -1 && arg->prec == -1 @@ -14099,22 +14107,32 @@ static Py_UCS4 formatchar(PyObject *v) { /* presume that the buffer is at least 3 characters long */ 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 (!PyLong_Check(v)) { + iobj = PyNumber_Index(v); + if (iobj == NULL) { + goto onError; + } + v = iobj; + Py_DECREF(iobj); + } /* Integer input truncated to a character */ - long x; x = PyLong_AsLong(v); if (x == -1 && PyErr_Occurred()) goto onError; if (x < 0 || x > MAX_UNICODE) { PyErr_SetString(PyExc_OverflowError, "%c arg not in range(0x110000)"); return (Py_UCS4) -1; } @@ -14302,21 +14320,22 @@ unicode_format_arg_parse(struct unicode_ return -1; } return 0; #undef FORMAT_READ } /* Format one argument. Supported conversion specifiers: - "s", "r", "a": any type - - "i", "d", "u", "o", "x", "X": int + - "i", "d", "u": int or float + - "o", "x", "X": int - "e", "E", "f", "F", "g", "G": float - "c": int or str (1 character) When possible, the output is written directly into the Unicode writer (ctx->writer). A string is created when padding is required. Return 0 if the argument has been formatted into *p_str, 1 if the argument has been written into ctx->writer, -1 on error. */ static int