Repository navigation
Invalid "equivalents" of the complex type constructor in docs #109218
Copy link
Copy link
Closed
Labels
docsDocumentation in the Doc dirDocumentation in the Doc dir
Description
The sphinx docs says:
class complex(real=0, imag=0)
[...]
Return a complex number with the value real + imag*1j or convert a string or number to a complex number.
[...]
The docstring (btw it doesn't mention a string as an argument):
>>> print(complex.__doc__)
Create a complex number from a real part and an optional imaginary part.
This is equivalent to (real + imag*1j) where imag defaults to 0.
That wrong, e.g.:
>>> complex(0.0, -0.0)
-0j
>>> 0.0 + (-0.0)*1j
0j
>>> complex(-0.0, -0.0)
(-0-0j)
>>> -0.0 + (-0.0)*1j
(-0+0j)
>>> complex(-0.0, 0.0)
(-0+0j)
>>> -0.0 + 0.0*1j
0jHere is an attempt (patch) to solve, let me know if this is worth a PR:
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index d9974c6350..78b85658ef 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -373,8 +373,8 @@ are always available. They are listed here in alphabetical order.
.. class:: complex(real=0, imag=0)
complex(string)
- Return a complex number with the value *real* + *imag*\*1j or convert a string
- or number to a complex number. If the first parameter is a string, it will
+ Create a complex number from a real part and an optional imaginary part
+ or convert a string to a complex number. If the first parameter is a string, it will
be interpreted as a complex number and the function must be called without a
second parameter. The second parameter can never be a string. Each argument
may be any numeric type (including complex). If *imag* is omitted, it
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index 0e96f54584..336b703233 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -886,9 +886,8 @@ complex.__new__ as complex_new
real as r: object(c_default="NULL") = 0
imag as i: object(c_default="NULL") = 0
-Create a complex number from a real part and an optional imaginary part.
-
-This is equivalent to (real + imag*1j) where imag defaults to 0.
+Create a complex number from a real part and an optional imaginary part
+or convert a string to a complex number.
[clinic start generated code]*/
static PyObject *Edit:
Another instance of this issue is in the cmath docs:
A Python complex number ``z`` is stored internally using *rectangular*
or *Cartesian* coordinates. It is completely determined by its *real
part* ``z.real`` and its *imaginary part* ``z.imag``. In other
words::
z == z.real + z.imag*1jE.g.:
>>> from cmath import inf
>>> complex(0.0, inf)
infj
>>> 0.0 + inf*1j
(nan+infj)Linked PRs
- gh-109218: Deprecate weird cases in the complex() constructor #119620
- gh-109218: Refactor tests for the complex() constructor #119635
- gh-109218: Improve documentation for the complex() constructor #119687
- [3.13] gh-109218: Refactor tests for the complex() constructor (GH-119635) #119795
- [3.12] gh-109218: Refactor tests for the complex() constructor (GH-119635) #119796
- [3.13] gh-109218: Improve documentation for the complex() constructor (GH-119687) #119803
- [3.12] gh-109218: Improve documentation for the complex() constructor (GH-119687) #119805
- gh-109218: announce removal of complex constructor deprecations in 3.19 #158212
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
docsDocumentation in the Doc dirDocumentation in the Doc dir
Activity
AA-Turner commentedon Sep 10, 2023
See also https://discuss.python.org/t/33433/
A
mdickinson commentedon Sep 11, 2023
Note that the two arguments to
complexcan themselves be complex numbers, so describing them as the real and imaginary part isn't always accurate:skirpichev commentedon Sep 12, 2023
Indeed, but in this form the "equivalency"
complex(r, i) == r + i*1jis also broken:Under the hood, instead, we have:
It's used in the current docstring, anyway.
Lets decide, however, whether this is a bug, regardless from the outcome in the mentioned discussion. Or not (as for
complexvseval(repr(complex))).pythongh-109218: Imaginary type and IEC 60559-compatible complex arit…
pythongh-109218: Imaginary type and IEC 60559-compatible complex arit…
pythongh-109218: Imaginary type and IEC 60559-compatible complex arit…
skirpichev commentedon May 25, 2024
@mdickinson, does this looks as an issue for you or we should accept imprecise docs? I don't see good ways to reword docs, while keeping them short and expressive.
Not sure, if this is a good idea to revival the d.p.o thread. On another hand, mentioned in the d.p.o variant with the imaginary type isn't explored well. Here is an implementation of the imaginary type & mixed-mode arithmetic rules: skirpichev#1 Among others, that should address current issue.
@serhiy-storchaka, do you think that it worth to discuss this proposal as a PEP?
So far major arguments against were:
I think that above implementation is more or less complete to estimate (a): so far most changes limited to arithmetic methods. (b) - this looks to be a strong one. On another hand, this feature of the C99+ standards is optional - that might be an explanation of partial adoption, while in the Python - complex arithmetic is a part of the language. For numeric C libraries, the GSL, for example, has own routines to do mixed-mode arithmetic...
serhiy-storchaka commentedon May 27, 2024
Currently the signature of complex is:
Both
realandimagare positional-or-keyword parameters. This allows absurd calls likecomplex(real="1j").I think that it should support several more limited signatures:
complex(number=0, /)complex(string, /)complex(real=0, imag=0)A string and complex number arguments should only be passed as a positional argument.
realandimagshould only be real numbers.skirpichev commentedon May 27, 2024
@serhiy-storchaka, yes I think this could solve the current issue like proposed in it's description. (I.e. we should remove all mentions of broken identities.)
At price of breaking compatibility. It seems, support for imaginary arguments exists since v2.2 (6d6c1a3). Not sure on what ground it was added, I doubt it's practically used.
... on another hand it might be viewed as a bug.
Shall I open a separate issue or it would be better to discuss this first on d.p.o?
mdickinson commentedon May 27, 2024
+1. I'd particularly like to see the form
complex(1 + 1j, 3 - 4j)deprecated, and eventually dropped.pythongh-109218: Deprecate weird cases in the complex() constructor
pythongh-109218: Deprecate weird cases in the complex() constructor
serhiy-storchaka commentedon May 27, 2024
I think this is the right issue, and no need to open another issue. My plan:
complex()builtin in 1.4 (8a5c5d2), but I do not think there is a use case for this. Accepting a complex number as the "real" argument could be an implementation artifact, but I have no explanation for accepting a complex number as the "imag" argument.#119620 implements the last two items.
pythongh-109218: Deprecate weird cases in the complex() constructor
8 remaining items
gh-109218: Improve documentation for the complex() constructor (GH-11…
pythongh-109218: Improve documentation for the complex() constructor (p…
[3.12] pythongh-109218: Improve documentation for the complex() const…
gh-109218: Deprecate weird cases in the complex() constructor (GH-119620
serhiy-storchaka commentedon May 30, 2024
Thank you for your reviews @skirpichev and @mdickinson.
[3.13] gh-109218: Improve documentation for the complex() constructor (…
[3.12] gh-109218: Improve documentation for the complex() constructor (…
pythongh-109218: Refactor tests for the complex() constructor (python…
pythongh-109218: Improve documentation for the complex() constructor (p…
pythongh-109218: Deprecate weird cases in the complex() constructor (p…
pythongh-109218: Refactor tests for the complex() constructor (python…
pythongh-109218: Improve documentation for the complex() constructor (p…
pythongh-109218: Deprecate weird cases in the complex() constructor (p…
[3.13] gh-109218: Refactor tests for the complex() constructor (GH-11…