Commit b7f5dcad authored by Larry Hastings's avatar Larry Hastings

Merge 3.4.0b2 release revisions back into mainline.

parents e7ee44e9 74fc8c47
...@@ -2080,9 +2080,17 @@ left undefined. ...@@ -2080,9 +2080,17 @@ left undefined.
.. method:: object.__index__(self) .. method:: object.__index__(self)
Called to implement :func:`operator.index`. Also called whenever Python needs Called to implement :func:`operator.index`, and whenever Python needs to
an integer object (such as in slicing, or in the built-in :func:`bin`, losslessly convert the numeric object to an integer object (such as in
:func:`hex` and :func:`oct` functions). Must return an integer. 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: .. _context-managers:
......
...@@ -196,7 +196,7 @@ def itn(n, digits=8, format=DEFAULT_FORMAT): ...@@ -196,7 +196,7 @@ def itn(n, digits=8, format=DEFAULT_FORMAT):
# A 0o200 byte indicates a positive number, a 0o377 byte a negative # A 0o200 byte indicates a positive number, a 0o377 byte a negative
# number. # number.
if 0 <= n < 8 ** (digits - 1): 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): elif format == GNU_FORMAT and -256 ** (digits - 1) <= n < 256 ** (digits - 1):
if n >= 0: if n >= 0:
s = bytearray([0o200]) s = bytearray([0o200])
......
...@@ -142,7 +142,6 @@ class FormatTest(unittest.TestCase): ...@@ -142,7 +142,6 @@ class FormatTest(unittest.TestCase):
testformat("%#+027.23X", big, "+0X0001234567890ABCDEF12345") testformat("%#+027.23X", big, "+0X0001234567890ABCDEF12345")
# same, except no 0 flag # same, except no 0 flag
testformat("%#+27.23X", big, " +0X001234567890ABCDEF12345") testformat("%#+27.23X", big, " +0X001234567890ABCDEF12345")
testformat("%x", float(big), "123456_______________", 6)
big = 0o12345670123456701234567012345670 # 32 octal digits big = 0o12345670123456701234567012345670 # 32 octal digits
testformat("%o", big, "12345670123456701234567012345670") testformat("%o", big, "12345670123456701234567012345670")
testformat("%o", -big, "-12345670123456701234567012345670") testformat("%o", -big, "-12345670123456701234567012345670")
...@@ -182,7 +181,6 @@ class FormatTest(unittest.TestCase): ...@@ -182,7 +181,6 @@ class FormatTest(unittest.TestCase):
testformat("%034.33o", big, "0012345670123456701234567012345670") testformat("%034.33o", big, "0012345670123456701234567012345670")
# base marker shouldn't change that # base marker shouldn't change that
testformat("%0#34.33o", big, "0o012345670123456701234567012345670") testformat("%0#34.33o", big, "0o012345670123456701234567012345670")
testformat("%o", float(big), "123456__________________________", 6)
# Some small ints, in both Python int and flavors). # 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")
...@@ -193,7 +191,6 @@ class FormatTest(unittest.TestCase): ...@@ -193,7 +191,6 @@ class FormatTest(unittest.TestCase):
testformat("%#x", 1, "0x1") testformat("%#x", 1, "0x1")
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", 1, "0o1") testformat("%#o", 1, "0o1")
testformat("%#o", 0, "0o0") testformat("%#o", 0, "0o0")
...@@ -210,12 +207,10 @@ class FormatTest(unittest.TestCase): ...@@ -210,12 +207,10 @@ class FormatTest(unittest.TestCase):
testformat("%x", -0x42, "-42") testformat("%x", -0x42, "-42")
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", 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("%r", "\u0378", "'\\u0378'") # non printable
testformat("%a", "\u0378", "'\\u0378'") # non printable testformat("%a", "\u0378", "'\\u0378'") # non printable
testformat("%r", "\u0374", "'\u0374'") # printable testformat("%r", "\u0374", "'\u0374'") # printable
......
...@@ -1126,6 +1126,35 @@ class UnicodeTest(string_tests.CommonTest, ...@@ -1126,6 +1126,35 @@ class UnicodeTest(string_tests.CommonTest,
self.assertEqual('%.1s' % "a\xe9\u20ac", 'a') self.assertEqual('%.1s' % "a\xe9\u20ac", 'a')
self.assertEqual('%.2s' % "a\xe9\u20ac", 'a\xe9') 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): def test_formatting_with_enum(self):
# issue18780 # issue18780
import enum import enum
......
...@@ -30,6 +30,10 @@ Core and Builtins ...@@ -30,6 +30,10 @@ Core and Builtins
- Issue #19969: PyBytes_FromFormatV() now raises an OverflowError if "%c" - Issue #19969: PyBytes_FromFormatV() now raises an OverflowError if "%c"
argument is not in range [0; 255]. 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 - 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 3.3, the function did nothing if the key already exists (if the current value
is a non-NULL pointer). is a non-NULL pointer).
......
...@@ -738,6 +738,17 @@ set_traverse(PySetObject *so, visitproc visit, void *arg) ...@@ -738,6 +738,17 @@ set_traverse(PySetObject *so, visitproc visit, void *arg)
static Py_hash_t static Py_hash_t
frozenset_hash(PyObject *self) frozenset_hash(PyObject *self)
{ {
/* Most of the constants in this hash algorithm are randomly choosen
large primes with "interesting bit patterns" and that passed
tests for good collision statistics on a variety of problematic
datasets such as:
ps = []
for r in range(21):
ps += itertools.combinations(range(20), r)
num_distinct_hashes = len({hash(frozenset(s)) for s in ps})
*/
PySetObject *so = (PySetObject *)self; PySetObject *so = (PySetObject *)self;
Py_uhash_t h, hash = 1927868237UL; Py_uhash_t h, hash = 1927868237UL;
setentry *entry; setentry *entry;
...@@ -754,8 +765,10 @@ frozenset_hash(PyObject *self) ...@@ -754,8 +765,10 @@ frozenset_hash(PyObject *self)
hashes so that many distinct combinations collapse to only hashes so that many distinct combinations collapse to only
a handful of distinct hash values. */ a handful of distinct hash values. */
h = entry->hash; h = entry->hash;
hash ^= (h ^ (h << 16) ^ 89869747UL) * 3644798167UL; hash ^= ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
} }
/* Make the final result spread-out in a different pattern
than the algorithem for tuples or other python objects. */
hash = hash * 69069U + 907133923UL; hash = hash * 69069U + 907133923UL;
if (hash == -1) if (hash == -1)
hash = 590923713UL; hash = 590923713UL;
......
...@@ -13988,7 +13988,7 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg) ...@@ -13988,7 +13988,7 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg)
return 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, * Return 1 if the number has been formatted into the writer,
* 0 if the number has been formatted into *p_output * 0 if the number has been formatted into *p_output
* -1 and raise an exception on error */ * -1 and raise an exception on error */
...@@ -14005,11 +14005,19 @@ mainformatlong(PyObject *v, ...@@ -14005,11 +14005,19 @@ mainformatlong(PyObject *v,
goto wrongtype; goto wrongtype;
if (!PyLong_Check(v)) { if (!PyLong_Check(v)) {
iobj = PyNumber_Long(v); if (type == 'o' || type == 'x' || type == 'X') {
if (iobj == NULL) { iobj = PyNumber_Index(v);
if (PyErr_ExceptionMatches(PyExc_TypeError)) if (iobj == NULL) {
goto wrongtype; return -1;
return -1; }
}
else {
iobj = PyNumber_Long(v);
if (iobj == NULL ) {
if (PyErr_ExceptionMatches(PyExc_TypeError))
goto wrongtype;
return -1;
}
} }
assert(PyLong_Check(iobj)); assert(PyLong_Check(iobj));
} }
...@@ -14079,8 +14087,18 @@ formatchar(PyObject *v) ...@@ -14079,8 +14087,18 @@ formatchar(PyObject *v)
goto onError; goto onError;
} }
else { else {
/* Integer input truncated to a character */ PyObject *iobj;
long x; 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 */
x = PyLong_AsLong(v); x = PyLong_AsLong(v);
if (x == -1 && PyErr_Occurred()) if (x == -1 && PyErr_Occurred())
goto onError; goto onError;
...@@ -14282,7 +14300,8 @@ unicode_format_arg_parse(struct unicode_formatter_t *ctx, ...@@ -14282,7 +14300,8 @@ unicode_format_arg_parse(struct unicode_formatter_t *ctx,
/* Format one argument. Supported conversion specifiers: /* Format one argument. Supported conversion specifiers:
- "s", "r", "a": any type - "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 - "e", "E", "f", "F", "g", "G": float
- "c": int or str (1 character) - "c": int or str (1 character)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment