diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-06-03 18:42:55 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-06-03 18:42:55 (GMT) |
commit | 16931c3559689cfa9d98e3b56e612b7e1e635b7a (patch) | |
tree | dd63cb2a5960a03eeb2a9560222ffebe03965817 /Objects/floatobject.c | |
parent | bb7f7327fea85d73e13950e83e5e39d57f7488df (diff) | |
download | cpython-16931c3559689cfa9d98e3b56e612b7e1e635b7a.zip cpython-16931c3559689cfa9d98e3b56e612b7e1e635b7a.tar.gz cpython-16931c3559689cfa9d98e3b56e612b7e1e635b7a.tar.bz2 |
Issue #26983: float() now always return an instance of exact float.
The deprecation warning is emitted if __float__ returns an instance of
a strict subclass of float. In a future versions of Python this can
be an error.
Diffstat (limited to 'Objects/floatobject.c')
-rw-r--r-- | Objects/floatobject.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 5b2742a..da600f4 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -215,35 +215,49 @@ double PyFloat_AsDouble(PyObject *op) { PyNumberMethods *nb; - PyFloatObject *fo; + PyObject *res; double val; - if (op && PyFloat_Check(op)) - return PyFloat_AS_DOUBLE((PyFloatObject*) op); - if (op == NULL) { PyErr_BadArgument(); return -1; } - if ((nb = Py_TYPE(op)->tp_as_number) == NULL || nb->nb_float == NULL) { - PyErr_SetString(PyExc_TypeError, "a float is required"); - return -1; + if (PyFloat_Check(op)) { + return PyFloat_AS_DOUBLE(op); } - fo = (PyFloatObject*) (*nb->nb_float) (op); - if (fo == NULL) - return -1; - if (!PyFloat_Check(fo)) { - Py_DECREF(fo); - PyErr_SetString(PyExc_TypeError, - "nb_float should return float object"); + nb = Py_TYPE(op)->tp_as_number; + if (nb == NULL || nb->nb_float == NULL) { + PyErr_Format(PyExc_TypeError, "must be real number, not %.50s", + op->ob_type->tp_name); return -1; } - val = PyFloat_AS_DOUBLE(fo); - Py_DECREF(fo); + res = (*nb->nb_float) (op); + if (res == NULL) { + return -1; + } + if (!PyFloat_CheckExact(res)) { + if (!PyFloat_Check(res)) { + PyErr_Format(PyExc_TypeError, + "%.50s.__float__ returned non-float (type %.50s)", + op->ob_type->tp_name, res->ob_type->tp_name); + Py_DECREF(res); + return -1; + } + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "%.50s.__float__ returned non-float (type %.50s). " + "The ability to return an instance of a strict subclass of float " + "is deprecated, and may be removed in a future version of Python.", + op->ob_type->tp_name, res->ob_type->tp_name)) { + Py_DECREF(res); + return -1; + } + } + val = PyFloat_AS_DOUBLE(res); + Py_DECREF(res); return val; } |