From: Serhiy Storchaka Date: Wed, 11 Dec 2013 19:26:36 +0000 (+0200) Subject: Issue #17576: Deprecation warning emitted now when __int__() or __index__() X-Git-Tag: v3.4.0b2~257 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c4f3212abc7e927f9218a7c82fae9e5639e272bc;p=python Issue #17576: Deprecation warning emitted now when __int__() or __index__() return not int instance. Introduced _PyLong_FromNbInt() and refactored PyLong_As*() functions. --- c4f3212abc7e927f9218a7c82fae9e5639e272bc diff --cc Misc/NEWS index edafe29b0f,0acfa72423..ad3cad97d3 --- a/Misc/NEWS +++ b/Misc/NEWS @@@ -10,11 -10,11 +10,14 @@@ Release date: 2014-01-0 Core and Builtins ----------------- + - Issue #17576: Deprecation warning emitted now when __int__() or __index__() + return not int instance. + - Issue #19932: Fix typo in import.h, missing whitespaces in function prototypes. +- Issue #19736: Add module-level statvfs constants defined for GNU/glibc + based systems. + - Issue #19729: In str.format(), fix recursive expansion in format spec. - Issue #19638: Fix possible crash / undefined behaviour from huge (more than 2 diff --cc Objects/longobject.c index 68a667e771,29040e60a9..9411216bcb --- a/Objects/longobject.c +++ b/Objects/longobject.c @@@ -634,9 -667,8 +673,8 @@@ _PyLong_AsUnsignedLongMask(PyObject *vv } unsigned long -PyLong_AsUnsignedLongMask(register PyObject *op) +PyLong_AsUnsignedLongMask(PyObject *op) { - PyNumberMethods *nb; PyLongObject *lo; unsigned long val; @@@ -1166,41 -1195,43 +1194,42 @@@ PyLong_AsLongLong(PyObject *vv { PyLongObject *v; PY_LONG_LONG bytes; - int one = 1; int res; + int do_decref = 0; /* if nb_int was called */ if (vv == NULL) { PyErr_BadInternalCall(); return -1; } - if (!PyLong_Check(vv)) { - PyNumberMethods *nb; - PyObject *io; - if ((nb = vv->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return -1; - } - io = (*nb->nb_int) (vv); - if (io == NULL) + + if (PyLong_Check(vv)) { + v = (PyLongObject *)vv; + } + else { + v = _PyLong_FromNbInt(vv); + if (v == NULL) return -1; - if (PyLong_Check(io)) { - bytes = PyLong_AsLongLong(io); - Py_DECREF(io); - return bytes; - } - Py_DECREF(io); - PyErr_SetString(PyExc_TypeError, "integer conversion failed"); - return -1; + do_decref = 1; } - v = (PyLongObject*)vv; + res = 0; switch(Py_SIZE(v)) { - case -1: return -(sdigit)v->ob_digit[0]; - case 0: return 0; - case 1: return v->ob_digit[0]; + case -1: + bytes = -(sdigit)v->ob_digit[0]; + break; + case 0: + bytes = 0; + break; + case 1: + bytes = v->ob_digit[0]; + break; + default: + res = _PyLong_AsByteArray((PyLongObject *)v, (unsigned char *)&bytes, - SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); ++ SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 1); + } + if (do_decref) { + Py_DECREF(v); } - res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, - SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 1); /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ if (res < 0) @@@ -1278,39 -1310,29 +1307,28 @@@ _PyLong_AsUnsignedLongLongMask(PyObjec } unsigned PY_LONG_LONG -PyLong_AsUnsignedLongLongMask(register PyObject *op) +PyLong_AsUnsignedLongLongMask(PyObject *op) { - PyNumberMethods *nb; PyLongObject *lo; unsigned PY_LONG_LONG val; - if (op && PyLong_Check(op)) - return _PyLong_AsUnsignedLongLongMask(op); + if (op == NULL) { + PyErr_BadInternalCall(); + return (unsigned long)-1; + } - if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return (unsigned PY_LONG_LONG)-1; + if (PyLong_Check(op)) { + return _PyLong_AsUnsignedLongLongMask(op); } - lo = (PyLongObject*) (*nb->nb_int) (op); + lo = _PyLong_FromNbInt(op); if (lo == NULL) return (unsigned PY_LONG_LONG)-1; - if (PyLong_Check(lo)) { - val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo); - Py_DECREF(lo); - if (PyErr_Occurred()) - return (unsigned PY_LONG_LONG)-1; - return val; - } - else - { - Py_DECREF(lo); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); - return (unsigned PY_LONG_LONG)-1; - } + + val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo); + Py_DECREF(lo); + return val; } -#undef IS_LITTLE_ENDIAN /* Get a C long long int from an int object or any object that has an __int__ method.