summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_complex.py12
-rw-r--r--Lib/test/test_doctest.py2
-rw-r--r--Lib/test/test_typing.py2
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2021-08-22-12-28-50.bpo-24234.n3oTdx.rst3
-rw-r--r--Objects/clinic/complexobject.c.h20
-rw-r--r--Objects/complexobject.c21
6 files changed, 57 insertions, 3 deletions
diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py
index abd7e39..1cd025e 100644
--- a/Lib/test/test_complex.py
+++ b/Lib/test/test_complex.py
@@ -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):
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index 8f761d7..571dc78 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -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
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 3bd5894..84521ee 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -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)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-08-22-12-28-50.bpo-24234.n3oTdx.rst b/Misc/NEWS.d/next/Core and Builtins/2021-08-22-12-28-50.bpo-24234.n3oTdx.rst
new file mode 100644
index 0000000..52397e9
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-08-22-12-28-50.bpo-24234.n3oTdx.rst
@@ -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.
diff --git a/Objects/clinic/complexobject.c.h b/Objects/clinic/complexobject.c.h
index 557fbf9..e7d8065 100644
--- a/Objects/clinic/complexobject.c.h
+++ b/Objects/clinic/complexobject.c.h
@@ -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]*/
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index 3e47949..cfe6c73 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -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 */