Skip to content

bpo-24234: implement complex.__complex__ #27887

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Lib/test/test_complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,18 @@ def __complex__(self):
self.assertEqual(complex(complex1(1j)), 2j)
self.assertRaises(TypeError, complex, complex2(1j))

def test___complex__(self):
z = 3 + 4j
self.assertEqual(z.__complex__(), z)
self.assertEqual(type(z.__complex__()), complex)

class complex_subclass(complex):
pass

z = complex_subclass(3 + 4j)
self.assertEqual(z.__complex__(), 3 + 4j)
self.assertEqual(type(z.__complex__()), complex)

@support.requires_IEEE_754
def test_constructor_special_numbers(self):
class complex2(complex):
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_doctest.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ def non_Python_modules(): r"""

>>> import builtins
>>> tests = doctest.DocTestFinder().find(builtins)
>>> 816 < len(tests) < 836 # approximate number of objects with docstrings
>>> 820 < len(tests) < 840 # approximate number of objects with docstrings
True
>>> real_tests = [t for t in tests if len(t.examples) > 0]
>>> len(real_tests) # objects that actually have doctests
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1533,11 +1533,11 @@ def test_supports_float(self):

def test_supports_complex(self):

# Note: complex itself doesn't have __complex__.
class C:
def __complex__(self):
return 0j

self.assertIsSubclass(complex, typing.SupportsComplex)
self.assertIsSubclass(C, typing.SupportsComplex)
self.assertNotIsSubclass(str, typing.SupportsComplex)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Implement the :meth:`__complex__` special method on the :class:`complex` type,
so a complex number ``z`` passes an ``isinstance(z, typing.SupportsComplex)``
check.
20 changes: 19 additions & 1 deletion Objects/clinic/complexobject.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions Objects/complexobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,29 @@ complex___format___impl(PyComplexObject *self, PyObject *format_spec)
return _PyUnicodeWriter_Finish(&writer);
}

/*[clinic input]
complex.__complex__

Convert this value to exact type complex.
[clinic start generated code]*/

static PyObject *
complex___complex___impl(PyComplexObject *self)
/*[clinic end generated code: output=e6b35ba3d275dc9c input=3589ada9d27db854]*/
{
if (PyComplex_CheckExact(self)) {
Py_INCREF(self);
return (PyObject *)self;
}
else {
return PyComplex_FromCComplex(self->cval);
}
}


static PyMethodDef complex_methods[] = {
COMPLEX_CONJUGATE_METHODDEF
COMPLEX___COMPLEX___METHODDEF
COMPLEX___GETNEWARGS___METHODDEF
COMPLEX___FORMAT___METHODDEF
{NULL, NULL} /* sentinel */
Expand Down