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/abstract.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/abstract.c')
-rw-r--r-- | Objects/abstract.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 3e1ff97..12dd6a1 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1351,21 +1351,39 @@ PyNumber_Float(PyObject *o) if (o == NULL) return null_error(); + if (PyFloat_CheckExact(o)) { + Py_INCREF(o); + return o; + } m = o->ob_type->tp_as_number; if (m && m->nb_float) { /* This should include subclasses of float */ PyObject *res = m->nb_float(o); - if (res && !PyFloat_Check(res)) { + double val; + if (!res || PyFloat_CheckExact(res)) { + return res; + } + if (!PyFloat_Check(res)) { PyErr_Format(PyExc_TypeError, - "__float__ returned non-float (type %.200s)", - res->ob_type->tp_name); + "%.50s.__float__ returned non-float (type %.50s)", + o->ob_type->tp_name, res->ob_type->tp_name); Py_DECREF(res); return NULL; } - return res; + /* Issue #26983: warn if 'res' not of exact type float. */ + 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.", + o->ob_type->tp_name, res->ob_type->tp_name)) { + Py_DECREF(res); + return NULL; + } + val = PyFloat_AS_DOUBLE(res); + Py_DECREF(res); + return PyFloat_FromDouble(val); } if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */ - PyFloatObject *po = (PyFloatObject *)o; - return PyFloat_FromDouble(po->ob_fval); + return PyFloat_FromDouble(PyFloat_AS_DOUBLE(o)); } return PyFloat_FromString(o); } |