diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2020-05-26 15:43:38 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-26 15:43:38 (GMT) |
commit | 578c3955e0222ec7b3146197467fbb0fcfae12fe (patch) | |
tree | 1314ca1eb6153feaf3fb1cae341784270ce24c32 /Objects/abstract.c | |
parent | 8ad052464a4e0aef9a11663b80f187087b773592 (diff) | |
download | cpython-578c3955e0222ec7b3146197467fbb0fcfae12fe.zip cpython-578c3955e0222ec7b3146197467fbb0fcfae12fe.tar.gz cpython-578c3955e0222ec7b3146197467fbb0fcfae12fe.tar.bz2 |
bpo-37999: No longer use __int__ in implicit integer conversions. (GH-15636)
Only __index__ should be used to make integer conversions lossless.
Diffstat (limited to 'Objects/abstract.c')
-rw-r--r-- | Objects/abstract.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 5b85b01..e819849 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1426,14 +1426,32 @@ PyNumber_Long(PyObject *o) } m = Py_TYPE(o)->tp_as_number; if (m && m->nb_int) { /* This should include subclasses of int */ - result = _PyLong_FromNbInt(o); - if (result != NULL && !PyLong_CheckExact(result)) { - Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); + /* Convert using the nb_int slot, which should return something + of exact type int. */ + result = m->nb_int(o); + if (!result || PyLong_CheckExact(result)) + return result; + if (!PyLong_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__int__ returned non-int (type %.200s)", + result->ob_type->tp_name); + Py_DECREF(result); + return NULL; + } + /* Issue #17576: warn if 'result' not of exact type int. */ + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + result->ob_type->tp_name)) { + Py_DECREF(result); + return NULL; } + Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); return result; } if (m && m->nb_index) { - result = _PyLong_FromNbIndexOrNbInt(o); + result = PyNumber_Index(o); if (result != NULL && !PyLong_CheckExact(result)) { Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); } @@ -1452,8 +1470,7 @@ PyNumber_Long(PyObject *o) } /* __trunc__ is specified to return an Integral type, but int() needs to return an int. */ - m = Py_TYPE(result)->tp_as_number; - if (m == NULL || (m->nb_index == NULL && m->nb_int == NULL)) { + if (!PyIndex_Check(result)) { PyErr_Format( PyExc_TypeError, "__trunc__ returned non-Integral (type %.200s)", @@ -1461,7 +1478,7 @@ PyNumber_Long(PyObject *o) Py_DECREF(result); return NULL; } - Py_SETREF(result, _PyLong_FromNbIndexOrNbInt(result)); + Py_SETREF(result, PyNumber_Index(result)); if (result != NULL && !PyLong_CheckExact(result)) { Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); } |