summaryrefslogtreecommitdiff
path: root/Objects/abstract.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-06-03 21:42:55 +0300
committerSerhiy Storchaka <storchaka@gmail.com>2016-06-03 21:42:55 +0300
commitbc91176aa05a4c7e67cffaf31286a86728bc7c99 (patch)
tree49ab2ec2a3910d8a78b5967ab23552cb1d894390 /Objects/abstract.c
parentaef4c16e861582792fa857dac81b72ded3bc6db7 (diff)
downloadcpython-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.c30
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);
}