mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	gh-109218: Improve documentation for the complex() constructor (GH-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.)
This commit is contained in:
		
							parent
							
								
									1c04c63ced
								
							
						
					
					
						commit
						ec1ba26460
					
				
					 4 changed files with 135 additions and 63 deletions
				
			
		|  | @ -43,10 +43,7 @@ Conversions to and from polar coordinates | ||||||
| 
 | 
 | ||||||
| A Python complex number ``z`` is stored internally using *rectangular* | A Python complex number ``z`` is stored internally using *rectangular* | ||||||
| or *Cartesian* coordinates.  It is completely determined by its *real | or *Cartesian* coordinates.  It is completely determined by its *real | ||||||
| part* ``z.real`` and its *imaginary part* ``z.imag``.  In other | part* ``z.real`` and its *imaginary part* ``z.imag``. | ||||||
| words:: |  | ||||||
| 
 |  | ||||||
|    z == z.real + z.imag*1j |  | ||||||
| 
 | 
 | ||||||
| *Polar coordinates* give an alternative way to represent a complex | *Polar coordinates* give an alternative way to represent a complex | ||||||
| number.  In polar coordinates, a complex number *z* is defined by the | number.  In polar coordinates, a complex number *z* is defined by the | ||||||
|  | @ -90,7 +87,7 @@ rectangular coordinates to polar coordinates and back. | ||||||
| .. function:: rect(r, phi) | .. function:: rect(r, phi) | ||||||
| 
 | 
 | ||||||
|    Return the complex number *x* with polar coordinates *r* and *phi*. |    Return the complex number *x* with polar coordinates *r* and *phi*. | ||||||
|    Equivalent to ``r * (math.cos(phi) + math.sin(phi)*1j)``. |    Equivalent to ``complex(r * math.cos(phi), r * math.sin(phi))``. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Power and logarithmic functions | Power and logarithmic functions | ||||||
|  |  | ||||||
|  | @ -141,10 +141,11 @@ are always available.  They are listed here in alphabetical order. | ||||||
|    See also :func:`format` for more information. |    See also :func:`format` for more information. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| .. class:: bool(x=False) | .. class:: bool(object=False, /) | ||||||
| 
 | 
 | ||||||
|    Return a Boolean value, i.e. one of ``True`` or ``False``.  *x* is converted |    Return a Boolean value, i.e. one of ``True`` or ``False``.  The argument | ||||||
|    using the standard :ref:`truth testing procedure <truth>`.  If *x* is false |    is converted using the standard :ref:`truth testing procedure <truth>`. | ||||||
|  |    If the argument is false | ||||||
|    or omitted, this returns ``False``; otherwise, it returns ``True``.  The |    or omitted, this returns ``False``; otherwise, it returns ``True``.  The | ||||||
|    :class:`bool` class is a subclass of :class:`int` (see :ref:`typesnumeric`). |    :class:`bool` class is a subclass of :class:`int` (see :ref:`typesnumeric`). | ||||||
|    It cannot be subclassed further.  Its only instances are ``False`` and |    It cannot be subclassed further.  Its only instances are ``False`` and | ||||||
|  | @ -153,7 +154,7 @@ are always available.  They are listed here in alphabetical order. | ||||||
|    .. index:: pair: Boolean; type |    .. index:: pair: Boolean; type | ||||||
| 
 | 
 | ||||||
|    .. versionchanged:: 3.7 |    .. versionchanged:: 3.7 | ||||||
|       *x* is now a positional-only parameter. |       The parameter is now positional-only. | ||||||
| 
 | 
 | ||||||
| .. function:: breakpoint(*args, **kws) | .. function:: breakpoint(*args, **kws) | ||||||
| 
 | 
 | ||||||
|  | @ -371,29 +372,73 @@ are always available.  They are listed here in alphabetical order. | ||||||
|       support for top-level ``await``, ``async for``, and ``async with``. |       support for top-level ``await``, ``async for``, and ``async with``. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| .. class:: complex(real=0, imag=0) | .. class:: complex(number=0, /) | ||||||
|            complex(string) |            complex(string, /) | ||||||
|  |            complex(real=0, imag=0) | ||||||
| 
 | 
 | ||||||
|    Return a complex number with the value *real* + *imag*\*1j or convert a string |    Convert a single string or number to a complex number, or create a | ||||||
|    or number to a complex number.  If the first parameter is a string, it will |    complex number from real and imaginary parts. | ||||||
|    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 |  | ||||||
|    defaults to zero and the constructor serves as a numeric conversion like |  | ||||||
|    :class:`int` and :class:`float`.  If both arguments are omitted, returns |  | ||||||
|    ``0j``. |  | ||||||
| 
 | 
 | ||||||
|  |    Examples: | ||||||
|  | 
 | ||||||
|  |    .. doctest:: | ||||||
|  | 
 | ||||||
|  |       >>> complex('+1.23') | ||||||
|  |       (1.23+0j) | ||||||
|  |       >>> complex('-4.5j') | ||||||
|  |       -4.5j | ||||||
|  |       >>> complex('-1.23+4.5j') | ||||||
|  |       (-1.23+4.5j) | ||||||
|  |       >>> complex('\t( -1.23+4.5J )\n') | ||||||
|  |       (-1.23+4.5j) | ||||||
|  |       >>> complex('-Infinity+NaNj') | ||||||
|  |       (-inf+nanj) | ||||||
|  |       >>> complex(1.23) | ||||||
|  |       (1.23+0j) | ||||||
|  |       >>> complex(imag=-4.5) | ||||||
|  |       -4.5j | ||||||
|  |       >>> complex(-1.23, 4.5) | ||||||
|  |       (-1.23+4.5j) | ||||||
|  | 
 | ||||||
|  |    If the argument is a string, it must contain either a real part (in the | ||||||
|  |    same format as for :func:`float`) or an imaginary part (in the same | ||||||
|  |    format but with a ``'j'`` or ``'J'`` suffix), or both real and imaginary | ||||||
|  |    parts (the sign of the imaginary part is mandatory in this case). | ||||||
|  |    The string can optionally be surrounded by whitespaces and the round | ||||||
|  |    parentheses ``'('`` and ``')'``, which are ignored. | ||||||
|  |    The string must not contain whitespace between ``'+'``, ``'-'``, the | ||||||
|  |    ``'j'`` or ``'J'`` suffix, and the decimal number. | ||||||
|  |    For example, ``complex('1+2j')`` is fine, but ``complex('1 + 2j')`` raises | ||||||
|  |    :exc:`ValueError`. | ||||||
|  |    More precisely, the input must conform to the :token:`~float:complexvalue` | ||||||
|  |    production rule in the following grammar, after parentheses and leading and | ||||||
|  |    trailing whitespace characters are removed: | ||||||
|  | 
 | ||||||
|  |    .. productionlist:: float | ||||||
|  |       complexvalue: `floatvalue` | | ||||||
|  |                   : `floatvalue` ("j" | "J") | | ||||||
|  |                   : `floatvalue` `sign` `absfloatvalue` ("j" | "J") | ||||||
|  | 
 | ||||||
|  |    If the argument is a number, the constructor serves as a numeric | ||||||
|  |    conversion like :class:`int` and :class:`float`. | ||||||
|    For a general Python object ``x``, ``complex(x)`` delegates to |    For a general Python object ``x``, ``complex(x)`` delegates to | ||||||
|    ``x.__complex__()``.  If :meth:`~object.__complex__` is not defined then it falls back |    ``x.__complex__()``. | ||||||
|    to :meth:`~object.__float__`.  If :meth:`!__float__` is not defined then it falls back |    If :meth:`~object.__complex__` is not defined then it falls back | ||||||
|  |    to :meth:`~object.__float__`. | ||||||
|  |    If :meth:`!__float__` is not defined then it falls back | ||||||
|    to :meth:`~object.__index__`. |    to :meth:`~object.__index__`. | ||||||
| 
 | 
 | ||||||
|    .. note:: |    If two arguments are provided or keyword arguments are used, each argument | ||||||
|  |    may be any numeric type (including complex). | ||||||
|  |    If both arguments are real numbers, return a complex number with the real | ||||||
|  |    component *real* and the imaginary component *imag*. | ||||||
|  |    If both arguments are complex numbers, return a complex number with the real | ||||||
|  |    component ``real.real-imag.imag`` and the imaginary component | ||||||
|  |    ``real.imag+imag.real``. | ||||||
|  |    If one of arguments is a real number, only its real component is used in | ||||||
|  |    the above expressions. | ||||||
| 
 | 
 | ||||||
|       When converting from a string, the string must not contain whitespace |    If all arguments are omitted, returns ``0j``. | ||||||
|       around the central ``+`` or ``-`` operator.  For example, |  | ||||||
|       ``complex('1+2j')`` is fine, but ``complex('1 + 2j')`` raises |  | ||||||
|       :exc:`ValueError`. |  | ||||||
| 
 | 
 | ||||||
|    The complex type is described in :ref:`typesnumeric`. |    The complex type is described in :ref:`typesnumeric`. | ||||||
| 
 | 
 | ||||||
|  | @ -682,21 +727,38 @@ are always available.  They are listed here in alphabetical order. | ||||||
|    elements of *iterable* for which *function* is false. |    elements of *iterable* for which *function* is false. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| .. class:: float(x=0.0) | .. class:: float(number=0.0, /) | ||||||
|  |            float(string, /) | ||||||
| 
 | 
 | ||||||
|    .. index:: |    .. index:: | ||||||
|       single: NaN |       single: NaN | ||||||
|       single: Infinity |       single: Infinity | ||||||
| 
 | 
 | ||||||
|    Return a floating point number constructed from a number or string *x*. |    Return a floating point number constructed from a number or a string. | ||||||
|  | 
 | ||||||
|  |    Examples: | ||||||
|  | 
 | ||||||
|  |    .. doctest:: | ||||||
|  | 
 | ||||||
|  |       >>> float('+1.23') | ||||||
|  |       1.23 | ||||||
|  |       >>> float('   -12345\n') | ||||||
|  |       -12345.0 | ||||||
|  |       >>> float('1e-003') | ||||||
|  |       0.001 | ||||||
|  |       >>> float('+1E6') | ||||||
|  |       1000000.0 | ||||||
|  |       >>> float('-Infinity') | ||||||
|  |       -inf | ||||||
| 
 | 
 | ||||||
|    If the argument is a string, it should contain a decimal number, optionally |    If the argument is a string, it should contain a decimal number, optionally | ||||||
|    preceded by a sign, and optionally embedded in whitespace.  The optional |    preceded by a sign, and optionally embedded in whitespace.  The optional | ||||||
|    sign may be ``'+'`` or ``'-'``; a ``'+'`` sign has no effect on the value |    sign may be ``'+'`` or ``'-'``; a ``'+'`` sign has no effect on the value | ||||||
|    produced.  The argument may also be a string representing a NaN |    produced.  The argument may also be a string representing a NaN | ||||||
|    (not-a-number), or positive or negative infinity.  More precisely, the |    (not-a-number), or positive or negative infinity. | ||||||
|    input must conform to the ``floatvalue`` production rule in the following |    More precisely, the input must conform to the :token:`~float:floatvalue` | ||||||
|    grammar, after leading and trailing whitespace characters are removed: |    production rule in the following grammar, after leading and trailing | ||||||
|  |    whitespace characters are removed: | ||||||
| 
 | 
 | ||||||
|    .. productionlist:: float |    .. productionlist:: float | ||||||
|       sign: "+" | "-" |       sign: "+" | "-" | ||||||
|  | @ -705,9 +767,10 @@ are always available.  They are listed here in alphabetical order. | ||||||
|       digit: <a Unicode decimal digit, i.e. characters in Unicode general category Nd> |       digit: <a Unicode decimal digit, i.e. characters in Unicode general category Nd> | ||||||
|       digitpart: `digit` (["_"] `digit`)* |       digitpart: `digit` (["_"] `digit`)* | ||||||
|       number: [`digitpart`] "." `digitpart` | `digitpart` ["."] |       number: [`digitpart`] "." `digitpart` | `digitpart` ["."] | ||||||
|       exponent: ("e" | "E") ["+" | "-"] `digitpart` |       exponent: ("e" | "E") [`sign`] `digitpart` | ||||||
|       floatnumber: number [`exponent`] |       floatnumber: `number` [`exponent`] | ||||||
|       floatvalue: [`sign`] (`floatnumber` | `infinity` | `nan`) |       absfloatvalue: `floatnumber` | `infinity` | `nan` | ||||||
|  |       floatvalue: [`sign`] `absfloatvalue` | ||||||
| 
 | 
 | ||||||
|    Case is not significant, so, for example, "inf", "Inf", "INFINITY", and |    Case is not significant, so, for example, "inf", "Inf", "INFINITY", and | ||||||
|    "iNfINity" are all acceptable spellings for positive infinity. |    "iNfINity" are all acceptable spellings for positive infinity. | ||||||
|  | @ -723,26 +786,13 @@ are always available.  They are listed here in alphabetical order. | ||||||
| 
 | 
 | ||||||
|    If no argument is given, ``0.0`` is returned. |    If no argument is given, ``0.0`` is returned. | ||||||
| 
 | 
 | ||||||
|    Examples:: |  | ||||||
| 
 |  | ||||||
|       >>> float('+1.23') |  | ||||||
|       1.23 |  | ||||||
|       >>> float('   -12345\n') |  | ||||||
|       -12345.0 |  | ||||||
|       >>> float('1e-003') |  | ||||||
|       0.001 |  | ||||||
|       >>> float('+1E6') |  | ||||||
|       1000000.0 |  | ||||||
|       >>> float('-Infinity') |  | ||||||
|       -inf |  | ||||||
| 
 |  | ||||||
|    The float type is described in :ref:`typesnumeric`. |    The float type is described in :ref:`typesnumeric`. | ||||||
| 
 | 
 | ||||||
|    .. versionchanged:: 3.6 |    .. versionchanged:: 3.6 | ||||||
|       Grouping digits with underscores as in code literals is allowed. |       Grouping digits with underscores as in code literals is allowed. | ||||||
| 
 | 
 | ||||||
|    .. versionchanged:: 3.7 |    .. versionchanged:: 3.7 | ||||||
|       *x* is now a positional-only parameter. |       The parameter is now positional-only. | ||||||
| 
 | 
 | ||||||
|    .. versionchanged:: 3.8 |    .. versionchanged:: 3.8 | ||||||
|       Falls back to :meth:`~object.__index__` if :meth:`~object.__float__` is not defined. |       Falls back to :meth:`~object.__index__` if :meth:`~object.__float__` is not defined. | ||||||
|  | @ -926,17 +976,36 @@ are always available.  They are listed here in alphabetical order. | ||||||
|       with the result after successfully reading input. |       with the result after successfully reading input. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| .. class:: int(x=0) | .. class:: int(number=0, /) | ||||||
|            int(x, base=10) |            int(string, /, base=10) | ||||||
| 
 | 
 | ||||||
|    Return an integer object constructed from a number or string *x*, or return |    Return an integer object constructed from a number or a string, or return | ||||||
|    ``0`` if no arguments are given.  If *x* defines :meth:`~object.__int__`, |    ``0`` if no arguments are given. | ||||||
|    ``int(x)`` returns ``x.__int__()``.  If *x* defines :meth:`~object.__index__`, | 
 | ||||||
|    it returns ``x.__index__()``.  If *x* defines :meth:`~object.__trunc__`, |    Examples: | ||||||
|  | 
 | ||||||
|  |    .. doctest:: | ||||||
|  | 
 | ||||||
|  |       >>> int(123.45) | ||||||
|  |       123 | ||||||
|  |       >>> int('123') | ||||||
|  |       123 | ||||||
|  |       >>> int('   -12_345\n') | ||||||
|  |       -12345 | ||||||
|  |       >>> int('FACE', 16) | ||||||
|  |       64206 | ||||||
|  |       >>> int('0xface', 0) | ||||||
|  |       64206 | ||||||
|  |       >>> int('01110011', base=2) | ||||||
|  |       115 | ||||||
|  | 
 | ||||||
|  |    If the argument defines :meth:`~object.__int__`, | ||||||
|  |    ``int(x)`` returns ``x.__int__()``.  If the argument defines :meth:`~object.__index__`, | ||||||
|  |    it returns ``x.__index__()``.  If the argument defines :meth:`~object.__trunc__`, | ||||||
|    it returns ``x.__trunc__()``. |    it returns ``x.__trunc__()``. | ||||||
|    For floating point numbers, this truncates towards zero. |    For floating point numbers, this truncates towards zero. | ||||||
| 
 | 
 | ||||||
|    If *x* is not a number or if *base* is given, then *x* must be a string, |    If the argument is not a number or if *base* is given, then it must be a string, | ||||||
|    :class:`bytes`, or :class:`bytearray` instance representing an integer |    :class:`bytes`, or :class:`bytearray` instance representing an integer | ||||||
|    in radix *base*.  Optionally, the string can be preceded by ``+`` or ``-`` |    in radix *base*.  Optionally, the string can be preceded by ``+`` or ``-`` | ||||||
|    (with no space in between), have leading zeros, be surrounded by whitespace, |    (with no space in between), have leading zeros, be surrounded by whitespace, | ||||||
|  | @ -966,7 +1035,7 @@ are always available.  They are listed here in alphabetical order. | ||||||
|       Grouping digits with underscores as in code literals is allowed. |       Grouping digits with underscores as in code literals is allowed. | ||||||
| 
 | 
 | ||||||
|    .. versionchanged:: 3.7 |    .. versionchanged:: 3.7 | ||||||
|       *x* is now a positional-only parameter. |       The first parameter is now positional-only. | ||||||
| 
 | 
 | ||||||
|    .. versionchanged:: 3.8 |    .. versionchanged:: 3.8 | ||||||
|       Falls back to :meth:`~object.__index__` if :meth:`~object.__int__` is not defined. |       Falls back to :meth:`~object.__index__` if :meth:`~object.__int__` is not defined. | ||||||
|  | @ -977,7 +1046,7 @@ are always available.  They are listed here in alphabetical order. | ||||||
|    .. versionchanged:: 3.11 |    .. versionchanged:: 3.11 | ||||||
|       :class:`int` string inputs and string representations can be limited to |       :class:`int` string inputs and string representations can be limited to | ||||||
|       help avoid denial of service attacks. A :exc:`ValueError` is raised when |       help avoid denial of service attacks. A :exc:`ValueError` is raised when | ||||||
|       the limit is exceeded while converting a string *x* to an :class:`int` or |       the limit is exceeded while converting a string to an :class:`int` or | ||||||
|       when converting an :class:`int` into a string would exceed the limit. |       when converting an :class:`int` into a string would exceed the limit. | ||||||
|       See the :ref:`integer string conversion length limitation |       See the :ref:`integer string conversion length limitation | ||||||
|       <int_max_str_digits>` documentation. |       <int_max_str_digits>` documentation. | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								Objects/clinic/complexobject.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										9
									
								
								Objects/clinic/complexobject.c.h
									
										
									
										generated
									
									
									
								
							|  | @ -94,9 +94,12 @@ PyDoc_STRVAR(complex_new__doc__, | ||||||
| "complex(real=0, imag=0)\n" | "complex(real=0, imag=0)\n" | ||||||
| "--\n" | "--\n" | ||||||
| "\n" | "\n" | ||||||
| "Create a complex number from a real part and an optional imaginary part.\n" | "Create a complex number from a string or numbers.\n" | ||||||
| "\n" | "\n" | ||||||
| "This is equivalent to (real + imag*1j) where imag defaults to 0."); | "If a string is given, parse it as a complex number.\n" | ||||||
|  | "If a single number is given, convert it to a complex number.\n" | ||||||
|  | "If the \'real\' or \'imag\' arguments are given, create a complex number\n" | ||||||
|  | "with the specified real and imaginary components."); | ||||||
| 
 | 
 | ||||||
| static PyObject * | static PyObject * | ||||||
| complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i); | complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i); | ||||||
|  | @ -157,4 +160,4 @@ skip_optional_pos: | ||||||
| exit: | exit: | ||||||
|     return return_value; |     return return_value; | ||||||
| } | } | ||||||
| /*[clinic end generated code: output=04e6261649967b30 input=a9049054013a1b77]*/ | /*[clinic end generated code: output=295ecfd71389d7fe input=a9049054013a1b77]*/ | ||||||
|  |  | ||||||
|  | @ -911,14 +911,17 @@ complex.__new__ as complex_new | ||||||
|     real as r: object(c_default="NULL") = 0 |     real as r: object(c_default="NULL") = 0 | ||||||
|     imag as i: 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. | Create a complex number from a string or numbers. | ||||||
| 
 | 
 | ||||||
| This is equivalent to (real + imag*1j) where imag defaults to 0. | If a string is given, parse it as a complex number. | ||||||
|  | If a single number is given, convert it to a complex number. | ||||||
|  | If the 'real' or 'imag' arguments are given, create a complex number | ||||||
|  | with the specified real and imaginary components. | ||||||
| [clinic start generated code]*/ | [clinic start generated code]*/ | ||||||
| 
 | 
 | ||||||
| static PyObject * | static PyObject * | ||||||
| complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) | complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) | ||||||
| /*[clinic end generated code: output=b6c7dd577b537dc1 input=f4c667f2596d4fd1]*/ | /*[clinic end generated code: output=b6c7dd577b537dc1 input=ff4268dc540958a4]*/ | ||||||
| { | { | ||||||
|     PyObject *tmp; |     PyObject *tmp; | ||||||
|     PyNumberMethods *nbr, *nbi = NULL; |     PyNumberMethods *nbr, *nbi = NULL; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Serhiy Storchaka
						Serhiy Storchaka