diff -r 6ff9eef4e7c3 Lib/test/test_cmath.py --- a/Lib/test/test_cmath.py Sat Oct 20 11:45:23 2012 +1000 +++ b/Lib/test/test_cmath.py Sat Oct 20 10:50:03 2012 +0100 @@ -165,7 +165,7 @@ # a variety of non-complex numbers, used to check that # non-complex return values from __complex__ give an error - non_complexes = ["not complex", 1, 5, 2., None, + non_complexes = ["not complex", 1, 5, None, object(), NotImplemented] # Now we introduce a variety of classes whose instances might @@ -235,6 +235,8 @@ self.assertEqual(f(FloatAndComplexOS()), f(cx_arg)) self.assertEqual(f(JustFloat()), f(flt_arg)) self.assertEqual(f(JustFloatOS()), f(flt_arg)) + # __complex__ should be permitted to return a float (issue 16290). + self.assertEqual(f(MyComplex(flt_arg)), f(flt_arg)) # TypeError should be raised for classes not providing # either __complex__ or __float__, even if they provide # __int__ or __index__. An old-style class diff -r 6ff9eef4e7c3 Objects/complexobject.c --- a/Objects/complexobject.c Sat Oct 20 11:45:23 2012 +1000 +++ b/Objects/complexobject.c Sat Oct 20 10:50:03 2012 +0100 @@ -296,13 +296,17 @@ newop = try_complex_special_method(op); if (newop) { - if (!PyComplex_Check(newop)) { + if (PyComplex_Check(newop)) { + cv = ((PyComplexObject *)newop)->cval; + } + else if (PyFloat_Check(newop)) { + cv.real = PyFloat_AS_DOUBLE((PyFloatObject *)newop); + cv.imag = 0.0; + } + else { PyErr_SetString(PyExc_TypeError, "__complex__ should return a complex object"); - Py_DECREF(newop); - return cv; } - cv = ((PyComplexObject *)newop)->cval; Py_DECREF(newop); return cv; }