summaryrefslogtreecommitdiffstats
path: root/Objects/floatobject.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-06-03 18:42:55 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-06-03 18:42:55 (GMT)
commit16931c3559689cfa9d98e3b56e612b7e1e635b7a (patch)
treedd63cb2a5960a03eeb2a9560222ffebe03965817 /Objects/floatobject.c
parentbb7f7327fea85d73e13950e83e5e39d57f7488df (diff)
downloadcpython-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.c46
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;
}