summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2019-06-01 21:05:48 (GMT)
committerGitHub <noreply@github.com>2019-06-01 21:05:48 (GMT)
commitbdbad71b9def0b86433de12cecca022eee91bd9f (patch)
tree147c8a3e08454a95e0e4900388d88f7b65430f63 /Objects
parent1a4d9ffa1aecd7e750195f2be06d3d16c7a3a88f (diff)
downloadcpython-bdbad71b9def0b86433de12cecca022eee91bd9f.zip
cpython-bdbad71b9def0b86433de12cecca022eee91bd9f.tar.gz
cpython-bdbad71b9def0b86433de12cecca022eee91bd9f.tar.bz2
bpo-20092. Use __index__ in constructors of int, float and complex. (GH-13108)
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c19
-rw-r--r--Objects/complexobject.c6
-rw-r--r--Objects/floatobject.c9
3 files changed, 31 insertions, 3 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 68d06ed..77d0914 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1373,6 +1373,13 @@ PyNumber_Long(PyObject *o)
}
return result;
}
+ if (m && m->nb_index) {
+ result = _PyLong_FromNbIndexOrNbInt(o);
+ if (result != NULL && !PyLong_CheckExact(result)) {
+ Py_SETREF(result, _PyLong_Copy((PyLongObject *)result));
+ }
+ return result;
+ }
trunc_func = _PyObject_LookupSpecial(o, &PyId___trunc__);
if (trunc_func) {
result = _PyObject_CallNoArg(trunc_func);
@@ -1480,6 +1487,18 @@ PyNumber_Float(PyObject *o)
Py_DECREF(res);
return PyFloat_FromDouble(val);
}
+ if (m && m->nb_index) {
+ PyObject *res = PyNumber_Index(o);
+ if (!res) {
+ return NULL;
+ }
+ double val = PyLong_AsDouble(res);
+ Py_DECREF(res);
+ if (val == -1.0 && PyErr_Occurred()) {
+ return NULL;
+ }
+ return PyFloat_FromDouble(val);
+ }
if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */
return PyFloat_FromDouble(PyFloat_AS_DOUBLE(o));
}
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index a5f9518..f78c0fd 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -984,7 +984,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i)
}
nbr = r->ob_type->tp_as_number;
- if (nbr == NULL || nbr->nb_float == NULL) {
+ if (nbr == NULL || (nbr->nb_float == NULL && nbr->nb_index == NULL)) {
PyErr_Format(PyExc_TypeError,
"complex() first argument must be a string or a number, "
"not '%.200s'",
@@ -996,7 +996,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i)
}
if (i != NULL) {
nbi = i->ob_type->tp_as_number;
- if (nbi == NULL || nbi->nb_float == NULL) {
+ if (nbi == NULL || (nbi->nb_float == NULL && nbi->nb_index == NULL)) {
PyErr_Format(PyExc_TypeError,
"complex() second argument must be a number, "
"not '%.200s'",
@@ -1052,7 +1052,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i)
/* The "imag" part really is entirely imaginary, and
contributes nothing in the real direction.
Just treat it as a double. */
- tmp = (*nbi->nb_float)(i);
+ tmp = PyNumber_Float(i);
if (tmp == NULL)
return NULL;
ci.real = PyFloat_AsDouble(tmp);
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 2bf7061..15cbe5c 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -246,6 +246,15 @@ PyFloat_AsDouble(PyObject *op)
nb = Py_TYPE(op)->tp_as_number;
if (nb == NULL || nb->nb_float == NULL) {
+ if (nb && nb->nb_index) {
+ PyObject *res = PyNumber_Index(op);
+ if (!res) {
+ return -1;
+ }
+ double val = PyLong_AsDouble(res);
+ Py_DECREF(res);
+ return val;
+ }
PyErr_Format(PyExc_TypeError, "must be real number, not %.50s",
op->ob_type->tp_name);
return -1;