Skip to content
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

Invalid "equivalents" of the complex type constructor in docs #109218

Closed
skirpichev opened this issue Sep 10, 2023 · 11 comments
Closed

Invalid "equivalents" of the complex type constructor in docs #109218

skirpichev opened this issue Sep 10, 2023 · 11 comments
Labels
docs Documentation in the Doc dir

Comments

@skirpichev
Copy link
Member

skirpichev commented Sep 10, 2023

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
0j
Here 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*1j

E.g.:

>>> from cmath import inf
>>> complex(0.0, inf)
infj
>>> 0.0 + inf*1j
(nan+infj)

Linked PRs

@skirpichev skirpichev added the docs Documentation in the Doc dir label Sep 10, 2023
@AA-Turner
Copy link
Member

See also https://discuss.python.org/t/33433/

A

@mdickinson
Copy link
Member

Note that the two arguments to complex can themselves be complex numbers, so describing them as the real and imaginary part isn't always accurate:

>>> complex(1+2j, 1-2j)
(3+3j)

@skirpichev
Copy link
Member Author

two arguments to complex can themselves be complex numbers

Indeed, but in this form the "equivalency" complex(r, i) == r + i*1j is also broken:

>>> complex(r := nan-infj, i := -inf+infj)
(nan-infj)
>>> r + i*1j
(nan+nanj)
>>> complex(r := -0.0-0j, i := 1+0j)
(-0+1j)
>>> r + i*1j
1j

Under the hood, instead, we have:

>>> complex(r.real - i.imag, i.real + r.imag)
(-0+1j)

describing them as the real and imaginary part isn't always accurate

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 complex vs eval(repr(complex))).

skirpichev added a commit to skirpichev/cpython that referenced this issue May 25, 2024
…hmetic

"Generally, mixed-mode arithmetic combining real and complex variables should
be performed directly, not by first coercing the real to complex, lest the sign
of zero be rendered uninformative; the same goes for combinations of pure
imaginary quantities with complex variables." (c) Kahan, W: Branch cuts for
complex elementary functions.

That's why C standards since C99 introduce imaginary types.  This patch
proposes similar extension to the Python language:

    * Added a new subtype (imaginary) of the complex type.  New type
      has few overloaded methods (conjugate() and __getnewargs__()).
    * Complex and imaginary types implement IEC 60559-compatible complex
      arithmetic (as specified by C11 Annex G).
    * Imaginary literals now produce instances of imaginary type.
    * cmath.infj/nanj were changed to be of imaginary type.
    * Modules ast, code, copy, marshal got support for imaginary type.
    * Few tests adapted to use complex, instead of imaginary literals
      - Lib/test/test_fractions.py
      - Lib/test/test_socket.py
      - Lib/test/test_str.py

Lets consider some (actually interrelated) problems, shown for unpatched code,
which could be solved on this way.

1) First, new code allows to use complex arithmetic for implementation of
   mathematical functions without special "corner cases".  Take the inverse
   hyperbolic sine as an example:

       >>> z = complex(-0.0, 2)
       >>> cmath.asinh(z)
       (-1.3169578969248166+1.5707963267948966j)
       >>> # naive textbook formula doesn't work:
       >>> cmath.log(z + cmath.sqrt(1 + z*z))
       (1.3169578969248166+1.5707963267948966j)
       >>> # "fixed" version does:
       >>> cmath.log(z + cmath.sqrt(complex(1 + (z*z).real, (z*z).imag)))
       (-1.3169578969248164+1.5707963267948966j)

2) Previously, we have only unsigned imaginary literals with the following
   semantics:

       ±a±bj = complex(±float(a), 0.0) ± complex(0.0, float(b))

   While this behaviour was well documented, most users would expect
   instead here:

       ±a±bj = complex(±float(a), ±float(b))

   i.e. that it follows to the rectangular notation for complex numbers.

   Things are worse, because the CPython docs sometimes asserts that the
   rectangular form is used and that some simple invariants holds.  For
   example, sphinx docs for the complex class says: "complex(real=0,
   imag=0) ...  Return a complex number with the value real + imag*1j ...".
   But:

       >>> complex(0.0, cmath.inf)
       infj
       >>> 0.0 + cmath.inf*1j
       (nan+infj)

3) The ``eval(repr(x)) == x`` invariant was broken for the complex type.  Below
   are simple examples with signed zero:

       >>> complex(-0.0, 1.0)  # also note funny signed integer zero below
       (-0+1j)
       >>> -0+1j
       1j
       >> -(0.0-1j)  # "correct" input for above with Python numeric literals
       (-0+1j)
       >>> -(0-1j)  # also "correct"; integer 0 matters!
       (-0+1j)
       >>> complex(1.0, -0.0)
       (1-0j)
       >>> 1-0j
       (1+0j)
       >>> -(-1 + 0j)
       (1-0j)

   Similar is true for complex numbers with other special components:

       >>> complex(0.0, -cmath.inf)
       -infj
       >>> -cmath.infj
       (-0-infj)
skirpichev added a commit to skirpichev/cpython that referenced this issue May 25, 2024
…hmetic

"Generally, mixed-mode arithmetic combining real and complex variables should
be performed directly, not by first coercing the real to complex, lest the sign
of zero be rendered uninformative; the same goes for combinations of pure
imaginary quantities with complex variables." (c) Kahan, W: Branch cuts for
complex elementary functions.

That's why C standards since C99 introduce imaginary types.  This patch
proposes similar extension to the Python language:

    * Added a new subtype (imaginary) of the complex type.  New type
      has few overloaded methods (conjugate() and __getnewargs__()).
    * Complex and imaginary types implement IEC 60559-compatible complex
      arithmetic (as specified by C11 Annex G).
    * Imaginary literals now produce instances of imaginary type.
    * cmath.infj/nanj were changed to be of imaginary type.
    * Modules ast, code, copy, marshal got support for imaginary type.
    * Few tests adapted to use complex, instead of imaginary literals
      - Lib/test/test_fractions.py
      - Lib/test/test_socket.py
      - Lib/test/test_str.py

Lets consider some (actually interrelated) problems, shown for unpatched code,
which could be solved on this way.

1) First, new code allows to use complex arithmetic for implementation of
   mathematical functions without special "corner cases".  Take the inverse
   hyperbolic sine as an example:

       >>> z = complex(-0.0, 2)
       >>> cmath.asinh(z)
       (-1.3169578969248166+1.5707963267948966j)
       >>> # naive textbook formula doesn't work:
       >>> cmath.log(z + cmath.sqrt(1 + z*z))
       (1.3169578969248166+1.5707963267948966j)
       >>> # "fixed" version does:
       >>> cmath.log(z + cmath.sqrt(complex(1 + (z*z).real, (z*z).imag)))
       (-1.3169578969248164+1.5707963267948966j)

2) Previously, we have only unsigned imaginary literals with the following
   semantics:

       ±a±bj = complex(±float(a), 0.0) ± complex(0.0, float(b))

   While this behaviour was well documented, most users would expect
   instead here:

       ±a±bj = complex(±float(a), ±float(b))

   i.e. that it follows to the rectangular notation for complex numbers.

   Things are worse, because the CPython docs sometimes asserts that the
   rectangular form is used and that some simple invariants holds.  For
   example, sphinx docs for the complex class says: "complex(real=0,
   imag=0) ...  Return a complex number with the value real + imag*1j ...".
   But:

       >>> complex(0.0, cmath.inf)
       infj
       >>> 0.0 + cmath.inf*1j
       (nan+infj)

3) The ``eval(repr(x)) == x`` invariant was broken for the complex type.  Below
   are simple examples with signed zero:

       >>> complex(-0.0, 1.0)  # also note funny signed integer zero below
       (-0+1j)
       >>> -0+1j
       1j
       >> -(0.0-1j)  # "correct" input for above with Python numeric literals
       (-0+1j)
       >>> -(0-1j)  # also "correct"; integer 0 matters!
       (-0+1j)
       >>> complex(1.0, -0.0)
       (1-0j)
       >>> 1-0j
       (1+0j)
       >>> -(-1 + 0j)
       (1-0j)

   Similar is true for complex numbers with other special components:

       >>> complex(0.0, -cmath.inf)
       -infj
       >>> -cmath.infj
       (-0-infj)
skirpichev added a commit to skirpichev/cpython that referenced this issue May 25, 2024
…hmetic

"Generally, mixed-mode arithmetic combining real and complex variables should
be performed directly, not by first coercing the real to complex, lest the sign
of zero be rendered uninformative; the same goes for combinations of pure
imaginary quantities with complex variables." (c) Kahan, W: Branch cuts for
complex elementary functions.

That's why C standards since C99 introduce imaginary types.  This patch
proposes similar extension to the Python language:

    * Added a new subtype (imaginary) of the complex type.  New type
      has few overloaded methods (conjugate() and __getnewargs__()).
    * Complex and imaginary types implement IEC 60559-compatible complex
      arithmetic (as specified by C11 Annex G).
    * Imaginary literals now produce instances of imaginary type.
    * cmath.infj/nanj were changed to be of imaginary type.
    * Modules ast, code, copy, marshal got support for imaginary type.
    * Few tests adapted to use complex, instead of imaginary literals
      - Lib/test/test_fractions.py
      - Lib/test/test_socket.py
      - Lib/test/test_str.py

Lets consider some (actually interrelated) problems, shown for unpatched code,
which could be solved on this way.

1) First, new code allows to use complex arithmetic for implementation of
   mathematical functions without special "corner cases".  Take the inverse
   hyperbolic sine as an example:

       >>> z = complex(-0.0, 2)
       >>> cmath.asinh(z)
       (-1.3169578969248166+1.5707963267948966j)
       >>> # naive textbook formula doesn't work:
       >>> cmath.log(z + cmath.sqrt(1 + z*z))
       (1.3169578969248166+1.5707963267948966j)
       >>> # "fixed" version does:
       >>> cmath.log(z + cmath.sqrt(complex(1 + (z*z).real, (z*z).imag)))
       (-1.3169578969248164+1.5707963267948966j)

2) Previously, we have only unsigned imaginary literals with the following
   semantics:

       ±a±bj = complex(±float(a), 0.0) ± complex(0.0, float(b))

   While this behaviour was well documented, most users would expect
   instead here:

       ±a±bj = complex(±float(a), ±float(b))

   i.e. that it follows to the rectangular notation for complex numbers.

   Things are worse, because the CPython docs sometimes asserts that the
   rectangular form is used and that some simple invariants holds.  For
   example, sphinx docs for the complex class says: "complex(real=0,
   imag=0) ...  Return a complex number with the value real + imag*1j ...".
   But:

       >>> complex(0.0, cmath.inf)
       infj
       >>> 0.0 + cmath.inf*1j
       (nan+infj)

3) The ``eval(repr(x)) == x`` invariant was broken for the complex type.  Below
   are simple examples with signed zero:

       >>> complex(-0.0, 1.0)  # also note funny signed integer zero below
       (-0+1j)
       >>> -0+1j
       1j
       >> -(0.0-1j)  # "correct" input for above with Python numeric literals
       (-0+1j)
       >>> -(0-1j)  # also "correct"; integer 0 matters!
       (-0+1j)
       >>> complex(1.0, -0.0)
       (1-0j)
       >>> 1-0j
       (1+0j)
       >>> -(-1 + 0j)
       (1-0j)

   Similar is true for complex numbers with other special components:

       >>> complex(0.0, -cmath.inf)
       -infj
       >>> -cmath.infj
       (-0-infj)
@skirpichev
Copy link
Member Author

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

  • (a) it’s a fairly large and involved change in comparison to the size of the problem it’s solving
  • (b) adoption of the C99 imaginary types has been disappointing

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
Copy link
Member

Currently the signature of complex is:

complex(real=0, imag=0)

Both real and imag are positional-or-keyword parameters. This allows absurd calls like complex(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. real and imag should only be real numbers.

@skirpichev
Copy link
Member Author

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

This allows absurd calls like complex(real="1j").

... 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
Copy link
Member

I think that it should support several more limited signatures:

+1. I'd particularly like to see the form complex(1 + 1j, 3 - 4j) deprecated, and eventually dropped.

serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this issue May 27, 2024
* Passing a string as the "real" keyword argument is now an error;
  it should only be passed as a single positional argument.
* Passing a complex number as the *real* or *imag* argument is now deprecated;
  it should only be passed as a single positional argument.
serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this issue May 27, 2024
* Passing a string as the "real" keyword argument is now an error;
  it should only be passed as a single positional argument.
* Passing a complex number as the *real* or *imag* argument is now deprecated;
  it should only be passed as a single positional argument.
@serhiy-storchaka
Copy link
Member

I think this is the right issue, and no need to open another issue. My plan:

  • Document the current behavior more accurately (without focusing on passing a string as the "real" keyword argument). The docstring may be more brief and do not include weird cases. This change should be backported.
  • Make passing a string as the "real" keyword argument an error. I do not think any deprecation is needed here. It looks like just an implementation artifact.
  • Deprecate accepting complex numbers as "real" and "image" arguments. This is the old behavior, since introduction of the 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.

serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this issue May 27, 2024
* Passing a string as the "real" keyword argument is now an error;
  it should only be passed as a single positional argument.
* Passing a complex number as the *real* or *imag* argument is now deprecated;
  it should only be passed as a single positional argument.
serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this issue May 27, 2024
* Share common classes.
* Use exactly representable floats and exact tests.
* Check the sign of zero components.
* Remove duplicated tests (mostly left after merging int and long).
* Reorder tests in more consistent way.
* Test more error messages.
* Add tests for missed cases.
@serhiy-storchaka
Copy link
Member

The tests for the complex() constructor currently are a mess, they were not cleaned up after Python 2, and some interesting cases are not covered. I refactor them in #119635, it is better to merge it before #119620.

@serhiy-storchaka
Copy link
Member

And #119687 is the documentation part. It adds more details and avoids using the real+imag*1j expression, which can be incorrect in corner cases. It uses a vague wording for parts which are planned for deprecation.

serhiy-storchaka added a commit that referenced this issue May 30, 2024
* Share common classes.
* Use exactly representable floats and exact tests.
* Check the sign of zero components.
* Remove duplicated tests (mostly left after merging int and long).
* Reorder tests in more consistent way.
* Test more error messages.
* Add tests for missed cases.
miss-islington pushed a commit to miss-islington/cpython that referenced this issue May 30, 2024
…GH-119635)

* Share common classes.
* Use exactly representable floats and exact tests.
* Check the sign of zero components.
* Remove duplicated tests (mostly left after merging int and long).
* Reorder tests in more consistent way.
* Test more error messages.
* Add tests for missed cases.
(cherry picked from commit bf098d4)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue May 30, 2024
…GH-119635)

* Share common classes.
* Use exactly representable floats and exact tests.
* Check the sign of zero components.
* Remove duplicated tests (mostly left after merging int and long).
* Reorder tests in more consistent way.
* Test more error messages.
* Add tests for missed cases.
(cherry picked from commit bf098d4)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
serhiy-storchaka added a commit that referenced this issue May 30, 2024
…9635) (GH-119796)

* Share common classes.
* Use exactly representable floats and exact tests.
* Check the sign of zero components.
* Remove duplicated tests (mostly left after merging int and long).
* Reorder tests in more consistent way.
* Test more error messages.
* Add tests for missed cases.
(cherry picked from commit bf098d4)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
serhiy-storchaka added a commit that referenced this issue May 30, 2024
…9687)

* Remove the equivalence with real+imag*1j which can be incorrect in corner
  cases (non-finite numbers, the sign of zeroes).
* Separately document the three roles of the constructor: parsing a string,
  converting a number, and constructing a complex from components.
* Document positional-only parameters of complex(), float(), int() and bool()
  as positional-only.
* Add examples for complex() and int().
* Specify the grammar of the string for complex().
* Improve the grammar of the string for float().
* Describe more explicitly the behavior when real and/or imag arguments are
  complex numbers. (This will be deprecated in future.)
miss-islington pushed a commit to miss-islington/cpython that referenced this issue May 30, 2024
…ythonGH-119687)

* Remove the equivalence with real+imag*1j which can be incorrect in corner
  cases (non-finite numbers, the sign of zeroes).
* Separately document the three roles of the constructor: parsing a string,
  converting a number, and constructing a complex from components.
* Document positional-only parameters of complex(), float(), int() and bool()
  as positional-only.
* Add examples for complex() and int().
* Specify the grammar of the string for complex().
* Improve the grammar of the string for float().
* Describe more explicitly the behavior when real and/or imag arguments are
  complex numbers. (This will be deprecated in future.)
(cherry picked from commit ec1ba26)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this issue May 30, 2024
…ructor (pythonGH-119687)

* Remove the equivalence with real+imag*1j which can be incorrect in corner
  cases (non-finite numbers, the sign of zeroes).
* Separately document the three roles of the constructor: parsing a string,
  converting a number, and constructing a complex from components.
* Document positional-only parameters of complex(), float(), int() and bool()
  as positional-only.
* Add examples for complex() and int().
* Specify the grammar of the string for complex().
* Improve the grammar of the string for float().
* Describe more explicitly the behavior when real and/or imag arguments are
  complex numbers. (This will be deprecated in future.)
(cherry picked from commit ec1ba26)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
serhiy-storchaka added a commit that referenced this issue May 30, 2024
)

* Passing a string as the "real" keyword argument is now an error;
  it should only be passed as a single positional argument.
* Passing a complex number as the "real" or "imag" argument is now deprecated;
  it should only be passed as a single positional argument.
@serhiy-storchaka
Copy link
Member

Thank you for your reviews @skirpichev and @mdickinson.

serhiy-storchaka added a commit that referenced this issue May 30, 2024
…GH-119687) (GH-119803)

* Remove the equivalence with real+imag*1j which can be incorrect in corner
  cases (non-finite numbers, the sign of zeroes).
* Separately document the three roles of the constructor: parsing a string,
  converting a number, and constructing a complex from components.
* Document positional-only parameters of complex(), float(), int() and bool()
  as positional-only.
* Add examples for complex() and int().
* Specify the grammar of the string for complex().
* Improve the grammar of the string for float().
* Describe more explicitly the behavior when real and/or imag arguments are
  complex numbers. (This will be deprecated in future.)
(cherry picked from commit ec1ba26)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
serhiy-storchaka added a commit that referenced this issue May 30, 2024
…GH-119687) (ПР-119805)

* Remove the equivalence with real+imag*1j which can be incorrect in corner
  cases (non-finite numbers, the sign of zeroes).
* Separately document the three roles of the constructor: parsing a string,
  converting a number, and constructing a complex from components.
* Document positional-only parameters of complex(), float(), int() and bool()
  as positional-only.
* Add examples for complex() and int().
* Specify the grammar of the string for complex().
* Improve the grammar of the string for float().
* Describe more explicitly the behavior when real and/or imag arguments are
  complex numbers. (This will be deprecated in future.)
(cherry picked from commit ec1ba26)
noahbkim pushed a commit to hudson-trading/cpython that referenced this issue Jul 11, 2024
…GH-119635)

* Share common classes.
* Use exactly representable floats and exact tests.
* Check the sign of zero components.
* Remove duplicated tests (mostly left after merging int and long).
* Reorder tests in more consistent way.
* Test more error messages.
* Add tests for missed cases.
noahbkim pushed a commit to hudson-trading/cpython that referenced this issue Jul 11, 2024
…ythonGH-119687)

* Remove the equivalence with real+imag*1j which can be incorrect in corner
  cases (non-finite numbers, the sign of zeroes).
* Separately document the three roles of the constructor: parsing a string,
  converting a number, and constructing a complex from components.
* Document positional-only parameters of complex(), float(), int() and bool()
  as positional-only.
* Add examples for complex() and int().
* Specify the grammar of the string for complex().
* Improve the grammar of the string for float().
* Describe more explicitly the behavior when real and/or imag arguments are
  complex numbers. (This will be deprecated in future.)
noahbkim pushed a commit to hudson-trading/cpython that referenced this issue Jul 11, 2024
…ythonGH-119620)

* Passing a string as the "real" keyword argument is now an error;
  it should only be passed as a single positional argument.
* Passing a complex number as the "real" or "imag" argument is now deprecated;
  it should only be passed as a single positional argument.
estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
…GH-119635)

* Share common classes.
* Use exactly representable floats and exact tests.
* Check the sign of zero components.
* Remove duplicated tests (mostly left after merging int and long).
* Reorder tests in more consistent way.
* Test more error messages.
* Add tests for missed cases.
estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
…ythonGH-119687)

* Remove the equivalence with real+imag*1j which can be incorrect in corner
  cases (non-finite numbers, the sign of zeroes).
* Separately document the three roles of the constructor: parsing a string,
  converting a number, and constructing a complex from components.
* Document positional-only parameters of complex(), float(), int() and bool()
  as positional-only.
* Add examples for complex() and int().
* Specify the grammar of the string for complex().
* Improve the grammar of the string for float().
* Describe more explicitly the behavior when real and/or imag arguments are
  complex numbers. (This will be deprecated in future.)
estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
…ythonGH-119620)

* Passing a string as the "real" keyword argument is now an error;
  it should only be passed as a single positional argument.
* Passing a complex number as the "real" or "imag" argument is now deprecated;
  it should only be passed as a single positional argument.
serhiy-storchaka added a commit that referenced this issue Aug 9, 2024
…9635) (GH-119795)

* Share common classes.
* Use exactly representable floats and exact tests.
* Check the sign of zero components.
* Remove duplicated tests (mostly left after merging int and long).
* Reorder tests in more consistent way.
* Test more error messages.
* Add tests for missed cases.
(cherry picked from commit bf098d4)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir
Projects
None yet
Development

No branches or pull requests

4 participants