cpython: 81f229262921 (original) (raw)
Mercurial > cpython
changeset 102829:81f229262921
Issue #26984: int() now always returns an instance of exact int. [#26984]
Serhiy Storchaka storchaka@gmail.com | |
---|---|
date | Sun, 21 Aug 2016 20:03:08 +0300 |
parents | cf18375732ae |
children | 81af0ab3db97 |
files | Lib/test/test_int.py Misc/NEWS Objects/abstract.c |
diffstat | 3 files changed, 29 insertions(+), 13 deletions(-)[+] [-] Lib/test/test_int.py 5 Misc/NEWS 2 Objects/abstract.c 35 |
line wrap: on
line diff
--- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -430,21 +430,24 @@ class IntTestCases(unittest.TestCase): with self.assertWarns(DeprecationWarning): n = int(bad_int) self.assertEqual(n, 1)
self.assertIs(type(n), int)[](#l1.7)
bad_int = BadInt2() with self.assertWarns(DeprecationWarning): n = int(bad_int) self.assertEqual(n, 1)
self.assertIs(type(n), int)[](#l1.13)
bad_int = TruncReturnsBadInt() with self.assertWarns(DeprecationWarning): n = int(bad_int) self.assertEqual(n, 1)
self.assertIs(type(n), int)[](#l1.19)
good_int = TruncReturnsIntSubclass() n = int(good_int) self.assertEqual(n, 1)
self.assertIs(type(n), bool)[](#l1.24)
self.assertIs(type(n), int)[](#l1.25) n = IntSubclass(good_int)[](#l1.26) self.assertEqual(n, 1)[](#l1.27) self.assertIs(type(n), IntSubclass)[](#l1.28)
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,8 @@ What's New in Python 3.6.0 beta 1 Core and Builtins ----------------- +- Issue #26984: int() now always returns an instance of exact int. +
- Issue #25604: Fix a minor bug in integer true division; this bug could potentially have caused off-by-one-ulp results on platforms with unreliable ldexp implementations.
--- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1281,6 +1281,7 @@ PyNumber_AsSsize_t(PyObject *item, PyObj PyObject * PyNumber_Long(PyObject *o) {
- PyObject *result; PyNumberMethods *m; PyObject *trunc_func; Py_buffer view; @@ -1296,29 +1297,39 @@ PyNumber_Long(PyObject o) } m = o->ob_type->tp_as_number; if (m && m->nb_int) { / This should include subclasses of int */
return (PyObject *)_PyLong_FromNbInt(o);[](#l3.15)
result = (PyObject *)_PyLong_FromNbInt(o);[](#l3.16)
if (result != NULL && !PyLong_CheckExact(result)) {[](#l3.17)
Py_SETREF(result, _PyLong_Copy((PyLongObject *)result));[](#l3.18)
}[](#l3.19)
} trunc_func = PyObject_LookupSpecial(o, &PyId___trunc_); if (trunc_func) {return result;[](#l3.20)
PyObject *truncated = PyEval_CallObject(trunc_func, NULL);[](#l3.24)
PyObject *int_instance;[](#l3.25)
result = PyEval_CallObject(trunc_func, NULL);[](#l3.26) Py_DECREF(trunc_func);[](#l3.27)
if (truncated == NULL || PyLong_Check(truncated))[](#l3.28)
return truncated;[](#l3.29)
if (result == NULL || PyLong_CheckExact(result)) {[](#l3.30)
return result;[](#l3.31)
}[](#l3.32)
if (PyLong_Check(result)) {[](#l3.33)
Py_SETREF(result, _PyLong_Copy((PyLongObject *)result));[](#l3.34)
return result;[](#l3.35)
}[](#l3.36) /* __trunc__ is specified to return an Integral type,[](#l3.37) but int() needs to return an int. */[](#l3.38)
m = truncated->ob_type->tp_as_number;[](#l3.39)
m = result->ob_type->tp_as_number;[](#l3.40) if (m == NULL || m->nb_int == NULL) {[](#l3.41) PyErr_Format([](#l3.42) PyExc_TypeError,[](#l3.43) "__trunc__ returned non-Integral (type %.200s)",[](#l3.44)
truncated->ob_type->tp_name);[](#l3.45)
Py_DECREF(truncated);[](#l3.46)
result->ob_type->tp_name);[](#l3.47)
Py_DECREF(result);[](#l3.48) return NULL;[](#l3.49) }[](#l3.50)
int_instance = (PyObject *)_PyLong_FromNbInt(truncated);[](#l3.51)
Py_DECREF(truncated);[](#l3.52)
return int_instance;[](#l3.53)
Py_SETREF(result, (PyObject *)_PyLong_FromNbInt(result));[](#l3.54)
if (result != NULL && !PyLong_CheckExact(result)) {[](#l3.55)
Py_SETREF(result, _PyLong_Copy((PyLongObject *)result));[](#l3.56)
}[](#l3.57)
} if (PyErr_Occurred()) return NULL;return result;[](#l3.58)
@@ -1340,7 +1351,7 @@ PyNumber_Long(PyObject *o) PyByteArray_GET_SIZE(o), 10); if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) {
PyObject *result, *bytes;[](#l3.66)
PyObject *bytes;[](#l3.67)
/* Copy to NUL-terminated buffer. */ bytes = PyBytes_FromStringAndSize((const char *)view.buf, view.len);