diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-06-03 21:42:55 +0300 |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-06-03 21:42:55 +0300 |
commit | bc91176aa05a4c7e67cffaf31286a86728bc7c99 (patch) | |
tree | 49ab2ec2a3910d8a78b5967ab23552cb1d894390 /Objects/abstract.c | |
parent | aef4c16e861582792fa857dac81b72ded3bc6db7 (diff) | |
download | cpython-bc91176aa05a4c7e67cffaf31286a86728bc7c99.tar.gz |
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 3e1ff97547..12dd6a16ce 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); } |