bpo-24234: implement complex.__complex__ (GH-27887)

Co-authored-by: Dong-hee Na <donghee.na92@gmail.com>
This commit is contained in:
Mark Dickinson 2021-08-23 09:15:49 +01:00 committed by GitHub
parent eec340ea3a
commit 6082bb5add
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 3 deletions

View File

@ -499,6 +499,18 @@ class ComplexTest(unittest.TestCase):
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):

View File

@ -668,7 +668,7 @@ plain ol' Python and is guaranteed to be available.
>>> 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

View File

@ -1533,11 +1533,11 @@ class ProtocolTests(BaseTestCase):
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)

View File

@ -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.

View File

@ -69,6 +69,24 @@ exit:
return return_value;
}
PyDoc_STRVAR(complex___complex____doc__,
"__complex__($self, /)\n"
"--\n"
"\n"
"Convert this value to exact type complex.");
#define COMPLEX___COMPLEX___METHODDEF \
{"__complex__", (PyCFunction)complex___complex__, METH_NOARGS, complex___complex____doc__},
static PyObject *
complex___complex___impl(PyComplexObject *self);
static PyObject *
complex___complex__(PyComplexObject *self, PyObject *Py_UNUSED(ignored))
{
return complex___complex___impl(self);
}
PyDoc_STRVAR(complex_new__doc__,
"complex(real=0, imag=0)\n"
"--\n"
@ -113,4 +131,4 @@ skip_optional_pos:
exit:
return return_value;
}
/*[clinic end generated code: output=056cac3226d94967 input=a9049054013a1b77]*/
/*[clinic end generated code: output=6d85094ace15677e input=a9049054013a1b77]*/

View File

@ -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 */