Index: Objects/complexobject.c
===================================================================
--- Objects/complexobject.c (revision 54183)
+++ Objects/complexobject.c (working copy)
@@ -252,9 +252,44 @@
PyComplex_AsCComplex(PyObject *op)
{
Py_complex cv;
+ PyObject *f, *r, *args;
+
+ /* If op is already of type PyComplex_Type, return its value */
if (PyComplex_Check(op)) {
return ((PyComplexObject *)op)->cval;
}
+ /* If not, use op's __complex__ method, if it exists */
+ if (PyObject_HasAttrString(op, "__complex__")) {
+ /* return value of -1 on failure */
+ cv.real = -1.;
+ cv.imag = 0.;
+
+ f = PyObject_GetAttrString(op, "__complex__");
+ if (f == NULL)
+ return cv;
+ args = PyTuple_New(0);
+ if (args == NULL) {
+ Py_DECREF(f);
+ return cv;
+ }
+ r = PyEval_CallObject(f, args);
+ Py_DECREF(args);
+ Py_DECREF(f);
+ if (r == NULL) {
+ return cv;
+ }
+ if (!PyComplex_Check(r)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__complex__ should return a complex object");
+ Py_DECREF(r);
+ return cv;
+ }
+ cv = ((PyComplexObject *)r)->cval;
+ Py_DECREF(r);
+ return cv;
+ }
+ /* If neither of the above works, interpret op as a float giving the
+ real part of the result, and fill in the imaginary part as 0. */
else {
cv.real = PyFloat_AsDouble(op);
cv.imag = 0.;
Index: Doc/api/concrete.tex
===================================================================
--- Doc/api/concrete.tex (revision 54183)
+++ Doc/api/concrete.tex (working copy)
@@ -443,7 +443,9 @@
\begin{cfuncdesc}{double}{PyFloat_AsDouble}{PyObject *pyfloat}
Return a C \ctype{double} representation of the contents of
- \var{pyfloat}.
+ \var{pyfloat}. If \var{pyfloat} is not a Python floating point
+ object but has a \method{__float__} method, this method will first
+ be called to convert \var{pyfloat} into a float.
\end{cfuncdesc}
\begin{cfuncdesc}{double}{PyFloat_AS_DOUBLE}{PyObject *pyfloat}
@@ -558,8 +560,10 @@
\end{cfuncdesc}
\begin{cfuncdesc}{Py_complex}{PyComplex_AsCComplex}{PyObject *op}
- Return the \ctype{Py_complex} value of the complex number
- \var{op}.
+ Return the \ctype{Py_complex} value of the complex number \var{op}.
+ If \var{op} is not a Python complex number object but has a
+ \method{__complex__} method, this method will first be called to
+ convert op to a Python complex number object.
\end{cfuncdesc}