diff options
author | Sergey B Kirpichev <skirpichev@gmail.com> | 2024-01-15 15:04:17 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-15 15:04:17 (GMT) |
commit | 0f2fa6150baf111a6c69d5d491c95c3c2ee60eaf (patch) | |
tree | e60136c4ac8da4e44cd3bdf4a702372be34a96d1 /Objects/complexobject.c | |
parent | ac10947ba79a15bfdaa3ca92c6864214648ab364 (diff) | |
download | cpython-0f2fa6150baf111a6c69d5d491c95c3c2ee60eaf.zip cpython-0f2fa6150baf111a6c69d5d491c95c3c2ee60eaf.tar.gz cpython-0f2fa6150baf111a6c69d5d491c95c3c2ee60eaf.tar.bz2 |
gh-109598: make PyComplex_RealAsDouble/ImagAsDouble use __complex__ (GH-109647)
`PyComplex_RealAsDouble()`/`PyComplex_ImagAsDouble` now try to convert
an object to a `complex` instance using its `__complex__()` method
before falling back to the ``__float__()`` method.
PyComplex_ImagAsDouble() also will not silently return 0.0 for
non-complex types anymore. Instead we try to call PyFloat_AsDouble()
and return 0.0 only if this call is successful.
Diffstat (limited to 'Objects/complexobject.c')
-rw-r--r-- | Objects/complexobject.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 0e96f54..d8b0e84 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -256,26 +256,51 @@ PyComplex_FromDoubles(double real, double imag) return PyComplex_FromCComplex(c); } +static PyObject * try_complex_special_method(PyObject *); + double PyComplex_RealAsDouble(PyObject *op) { + double real = -1.0; + if (PyComplex_Check(op)) { - return ((PyComplexObject *)op)->cval.real; + real = ((PyComplexObject *)op)->cval.real; } else { - return PyFloat_AsDouble(op); + PyObject* newop = try_complex_special_method(op); + if (newop) { + real = ((PyComplexObject *)newop)->cval.real; + Py_DECREF(newop); + } else if (!PyErr_Occurred()) { + real = PyFloat_AsDouble(op); + } } + + return real; } double PyComplex_ImagAsDouble(PyObject *op) { + double imag = -1.0; + if (PyComplex_Check(op)) { - return ((PyComplexObject *)op)->cval.imag; + imag = ((PyComplexObject *)op)->cval.imag; } else { - return 0.0; + PyObject* newop = try_complex_special_method(op); + if (newop) { + imag = ((PyComplexObject *)newop)->cval.imag; + Py_DECREF(newop); + } else if (!PyErr_Occurred()) { + PyFloat_AsDouble(op); + if (!PyErr_Occurred()) { + imag = 0.0; + } + } } + + return imag; } static PyObject * |