From 5d5b6809f96699ce994c40d812afd4d8344d56ac Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 14 Sep 2025 07:29:14 +0300 Subject: [PATCH 1/6] Fix formatting --- peps/pep-0791.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0791.rst b/peps/pep-0791.rst index 9b1dd749a85..df837d81d4a 100644 --- a/peps/pep-0791.rst +++ b/peps/pep-0791.rst @@ -64,7 +64,7 @@ proposed there were only two integer-related functions: :external+py3.14:func:`~math.factorial` (accepting also :class:`float`'s, like other functions in the module) and :external+py3.14:func:`~math.gcd` (moved from the -::external+py3.14:mod:`fractions` module). Then +:external+py3.14:mod:`fractions` module). Then :external+py3.14:func:`~math.isqrt`, :external+py3.14:func:`~math.comb` and :external+py3.14:func:`~math.perm` were added, and addition of the new module was `proposed second time `_, From b8f63c060d6baf17967987306d2e60505bc180ec Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 14 Sep 2025 14:23:37 +0300 Subject: [PATCH 2/6] Rephrase Motivation --- peps/pep-0791.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0791.rst b/peps/pep-0791.rst index df837d81d4a..c139d526282 100644 --- a/peps/pep-0791.rst +++ b/peps/pep-0791.rst @@ -29,7 +29,7 @@ over time the module was populated with functions that aren't related to the C standard or floating-point arithmetics. Now it's much harder to describe module scope, content and interfaces (returned values or accepted arguments). -For example, the :external+py3.14:mod:`math` module documentation says: "Except +For example, following statement from the documentation: "Except when explicitly noted otherwise, all return values are floats." This is no longer true: *None* of the functions listed in the `Number-theoretic functions `_ From ca635f80145cedfbc390760b0928eeaab02bd636 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 14 Sep 2025 14:28:41 +0300 Subject: [PATCH 3/6] Reindent --- peps/pep-0791.rst | 120 ++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 57 deletions(-) diff --git a/peps/pep-0791.rst b/peps/pep-0791.rst index c139d526282..baea3555924 100644 --- a/peps/pep-0791.rst +++ b/peps/pep-0791.rst @@ -16,27 +16,27 @@ Abstract ======== This PEP proposes a new module for number-theoretical, combinatorial and other -functions defined for integer arguments, like -:external+py3.14:func:`math.gcd` or :external+py3.14:func:`math.isqrt`. +functions defined for integer arguments, like :external+py3.14:func:`math.gcd` +or :external+py3.14:func:`math.isqrt`. Motivation ========== -The :external+py3.14:mod:`math` documentation says: "This module provides access -to the mathematical functions defined by the C standard." But, -over time the module was populated with functions that aren't related to -the C standard or floating-point arithmetics. Now it's much harder to describe +The :external+py3.14:mod:`math` documentation says: "This module provides +access to the mathematical functions defined by the C standard." But, over +time the module was populated with functions that aren't related to the C +standard or floating-point arithmetics. Now it's much harder to describe module scope, content and interfaces (returned values or accepted arguments). -For example, following statement from the documentation: "Except -when explicitly noted otherwise, all return values are floats." This is no -longer true: *None* of the functions listed in the `Number-theoretic -functions `_ -subsection of the documentation return a float, but the -documentation doesn't say so. In the documentation for the proposed ``intmath`` module the sentence "All -return values are integers." would be accurate. In a similar way we -can simplify the description of the accepted arguments for functions in both the +For example, following statement from the documentation: "Except when +explicitly noted otherwise, all return values are floats." This is no longer +true: *None* of the functions listed in the `Number-theoretic functions +`_ +subsection of the documentation return a float, but the documentation doesn't +say so. In the documentation for the proposed ``intmath`` module the sentence +"All return values are integers." would be accurate. In a similar way we can +simplify the description of the accepted arguments for functions in both the new module and in :external+py3.14:mod:`math`. Now it's a lot harder to satisfy people's expectations about the module @@ -45,12 +45,13 @@ return an exact answer? Many languages, Python packages (like :pypi:`scipy`) or pocket calculators have functions with same or similar name, that return a floating-point value, which is only an approximation in this example. -Apparently, the :external+py3.14:mod:`math` module can't serve as a catch-all place -for mathematical functions since we also have the :external+py3.14:mod:`cmath` and -:external+py3.14:mod:`statistics` modules. Let's do the same for integer-related -functions. It provides shared context, which reduces verbosity in the -documentation and conceptual load. It also aids discoverability through -grouping related functions and makes IDE suggestions more helpful. +Apparently, the :external+py3.14:mod:`math` module can't serve as a catch-all +place for mathematical functions since we also have the +:external+py3.14:mod:`cmath` and :external+py3.14:mod:`statistics` modules. +Let's do the same for integer-related functions. It provides shared context, +which reduces verbosity in the documentation and conceptual load. It also aids +discoverability through grouping related functions and makes IDE suggestions +more helpful. Currently the :external+py3.14:mod:`math` module code in the CPython is around 4200LOC, from which the new module code is roughly 1/3 (1300LOC). This is @@ -62,54 +63,59 @@ And this situation tends to get worse. When the module split `was first proposed `_, there were only two integer-related functions: -:external+py3.14:func:`~math.factorial` (accepting also :class:`float`'s, like other -functions in the module) and :external+py3.14:func:`~math.gcd` (moved from the -:external+py3.14:mod:`fractions` module). Then +:external+py3.14:func:`~math.factorial` (accepting also :class:`float`'s, like +other functions in the module) and :external+py3.14:func:`~math.gcd` (moved +from the :external+py3.14:mod:`fractions` module). Then :external+py3.14:func:`~math.isqrt`, :external+py3.14:func:`~math.comb` and :external+py3.14:func:`~math.perm` were added, and addition of the new module was `proposed second time `_, so all new functions would go directly to it, without littering the -:external+py3.14:mod:`math` namespace. -Now there are six functions and :external+py3.14:func:`~math.factorial` doesn't accept -:class:`float`'s anymore. +:external+py3.14:mod:`math` namespace. Now there are six functions and +:external+py3.14:func:`~math.factorial` doesn't accept :class:`float`'s +anymore. Some possible additions, among those proposed in the initial discussion thread -and issue -`python/cpython#81313 `_ are: +and issue `python/cpython#81313 +`_ are: * ``c_div()`` and ``n_div()`` --- for integer division with rounding towards positive infinity (ceiling divide) and to the nearest integer, see `relevant discussion thread `_. This is reinvented several times in the stdlib, e.g. in the :mod:`datetime` and the :mod:`fractions`. -* ``gcdext()`` --- to solve linear `Diophantine equation `_ in two variables (the +* ``gcdext()`` --- to solve linear `Diophantine equation + `_ in two variables (the :external+py3.14:class:`int` implementation actually includes an extended Euclidean algorithm) -* ``isqrt_rem()`` --- to return both an integer square root and a remainder (which is non-zero only if - the integer isn't a perfect square) -* ``ilog()`` --- integer logarithm, :external+py3.14:func:`math.log` - has special handling for integer arguments. It's unique (with respect to other module - functions) and not documented so far, see issue - `python/cpython#120950 `_. -* ``fibonacci()`` --- `Fibonacci sequence `_. +* ``isqrt_rem()`` --- to return both an integer square root and a remainder + (which is non-zero only if the integer isn't a perfect square) + +* ``ilog()`` --- integer logarithm, :external+py3.14:func:`math.log` has + special handling for integer arguments. It's unique (with respect to other + module functions) and not documented so far, see issue `python/cpython#120950 + `_. +* ``fibonacci()`` --- `Fibonacci sequence + `_. Rationale ========= Why not fix the :external+py3.14:mod:`math` module documentation instead? -Sure, we can be much more vague in the module preamble (i.e. roughly say -that "the :external+py3.14:mod:`math` module contains some mathematical -functions"), we can accurately describe input/output for each function -and it's behavior (e.g. whether the :external+py3.14:func:`~math.factorial` -output is exact or not, like e.g. the `scipy.special.factorial `_, per default). - -But the major issue is that the current module mixes different, almost non-interlaced -application domains. Adding more documentation will just highlight this and -make the issue worse for end users (more text to read/skip). And it will not -fix issue with discoverability (to know in which module to find a function, and -that it can be found at all, you need to look at all the functions in the -module), nor with tab-completion. +Sure, we can be much more vague in the module preamble (i.e. roughly say that +"the :external+py3.14:mod:`math` module contains some mathematical functions"), +we can accurately describe input/output for each function and it's behavior +(e.g. whether the :external+py3.14:func:`~math.factorial` output is exact or +not, like e.g. the `scipy.special.factorial +`_, +per default). + +But the major issue is that the current module mixes different, almost +non-interlaced application domains. Adding more documentation will just +highlight this and make the issue worse for end users (more text to read/skip). +And it will not fix issue with discoverability (to know in which module to find +a function, and that it can be found at all, you need to look at all the +functions in the module), nor with tab-completion. Specification @@ -163,8 +169,8 @@ How to Teach This ================= The new module will be a place for functions, that 1) accept -:external+py3.14:class:`int`-like arguments and also return integers, and 2) are -also in the field of arbitrary-precision integer arithmetic, i.e. have no +:external+py3.14:class:`int`-like arguments and also return integers, and 2) +are also in the field of arbitrary-precision integer arithmetic, i.e. have no dependency on the platform floating-point format or behaviour and/or on the platform math library (``libm``). @@ -193,8 +199,8 @@ Other proposed names include ``ntheory`` (like SymPy's submodule), ``integermath``, ``zmath``, ``dmath`` and ``imaths``. As a variant, the new module can be added as a submodule of the -:external+py3.14:mod:`math`: ``integer`` (most preferred), ``discrete`` -or ``ntheory``. +:external+py3.14:mod:`math`: ``integer`` (most preferred), ``discrete`` or +``ntheory``. isqrt() renaming @@ -210,13 +216,13 @@ would be confusing to give it the same name (under a different module). Acknowledgements ================ -Thanks to Tim Peters for reviving the idea of splitting the :external+py3.14:mod:`math` -module. Thanks to Neil Girdhar for substantial improvements of -the initial draft. +Thanks to Tim Peters for reviving the idea of splitting the +:external+py3.14:mod:`math` module. Thanks to Neil Girdhar for substantial +improvements of the initial draft. Copyright ========= -This document is placed in the public domain or under the -CC0-1.0-Universal license, whichever is more permissive. +This document is placed in the public domain or under the CC0-1.0-Universal +license, whichever is more permissive. From be208639f83d26685b94ea6027416b85097c98b4 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 15 Sep 2025 07:19:20 +0300 Subject: [PATCH 4/6] Restore back "Open Issues" section for module name --- peps/pep-0791.rst | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/peps/pep-0791.rst b/peps/pep-0791.rst index baea3555924..ad009753556 100644 --- a/peps/pep-0791.rst +++ b/peps/pep-0791.rst @@ -122,7 +122,8 @@ Specification ============= The PEP proposes moving the following integer-related functions to a new -module, called ``intmath``: +module, called ``intmath`` (see `Open Issues`_ for alternatives for +it's name): * :external+py3.14:func:`~math.comb` * :external+py3.14:func:`~math.factorial` @@ -189,8 +190,18 @@ Reference Implementation Rejected ideas ============== -Module name ------------ +isqrt() renaming +--------------------------------------------- + +There was a brief discussion about exposing :external+py3.14:func:`math.isqrt` +as ``imath.sqrt`` in the same way that :external+py3.14:func:`cmath.sqrt` is +the complex version of :external+py3.14:func:`math.sqrt`. However, ``isqrt`` +is ultimately a different function: it is the floor of the square root. It +would be confusing to give it the same name (under a different module). + + +Open Issues +=========== `Polling showed `_ ``intmath`` as most popular candidate with ``imath`` as a second winner. @@ -200,17 +211,7 @@ Other proposed names include ``ntheory`` (like SymPy's submodule), As a variant, the new module can be added as a submodule of the :external+py3.14:mod:`math`: ``integer`` (most preferred), ``discrete`` or -``ntheory``. - - -isqrt() renaming ---------------------------------------------- - -There was a brief discussion about exposing :external+py3.14:func:`math.isqrt` -as ``imath.sqrt`` in the same way that :external+py3.14:func:`cmath.sqrt` is -the complex version of :external+py3.14:func:`math.sqrt`. However, ``isqrt`` -is ultimately a different function: it is the floor of the square root. It -would be confusing to give it the same name (under a different module). +``ntheory`` (author preference). Acknowledgements From 0581100a5fdc386fc060eb1a7879972d03f7f6db Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 15 Sep 2025 13:09:58 +0300 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- peps/pep-0791.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/peps/pep-0791.rst b/peps/pep-0791.rst index ad009753556..11f09dd3d92 100644 --- a/peps/pep-0791.rst +++ b/peps/pep-0791.rst @@ -29,13 +29,13 @@ time the module was populated with functions that aren't related to the C standard or floating-point arithmetics. Now it's much harder to describe module scope, content and interfaces (returned values or accepted arguments). -For example, following statement from the documentation: "Except when +For example, the following statement from the documentation: "Except when explicitly noted otherwise, all return values are floats." This is no longer true: *None* of the functions listed in the `Number-theoretic functions `_ subsection of the documentation return a float, but the documentation doesn't say so. In the documentation for the proposed ``intmath`` module the sentence -"All return values are integers." would be accurate. In a similar way we can +"All return values are integers" would be accurate. In a similar way we can simplify the description of the accepted arguments for functions in both the new module and in :external+py3.14:mod:`math`. @@ -81,7 +81,7 @@ and issue `python/cpython#81313 * ``c_div()`` and ``n_div()`` --- for integer division with rounding towards positive infinity (ceiling divide) and to the nearest integer, see `relevant discussion thread `_. This is reinvented - several times in the stdlib, e.g. in the :mod:`datetime` and the + several times in the stdlib, e.g. in :mod:`datetime` and :mod:`fractions`. * ``gcdext()`` --- to solve linear `Diophantine equation `_ in two variables (the @@ -104,16 +104,16 @@ Rationale Why not fix the :external+py3.14:mod:`math` module documentation instead? Sure, we can be much more vague in the module preamble (i.e. roughly say that "the :external+py3.14:mod:`math` module contains some mathematical functions"), -we can accurately describe input/output for each function and it's behavior +we can accurately describe input/output for each function and its behavior (e.g. whether the :external+py3.14:func:`~math.factorial` output is exact or -not, like e.g. the `scipy.special.factorial +not, like the `scipy.special.factorial `_, per default). But the major issue is that the current module mixes different, almost non-interlaced application domains. Adding more documentation will just highlight this and make the issue worse for end users (more text to read/skip). -And it will not fix issue with discoverability (to know in which module to find +And it will not fix the issue with discoverability (to know in which module to find a function, and that it can be found at all, you need to look at all the functions in the module), nor with tab-completion. From 1dc904b230a1eb4b2d469a3863d9c6f42a7658c6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 18 Sep 2025 15:31:05 +0200 Subject: [PATCH 6/6] Update peps/pep-0791.rst Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- peps/pep-0791.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0791.rst b/peps/pep-0791.rst index 11f09dd3d92..e9b1726fe75 100644 --- a/peps/pep-0791.rst +++ b/peps/pep-0791.rst @@ -71,7 +71,7 @@ from the :external+py3.14:mod:`fractions` module). Then was `proposed second time `_, so all new functions would go directly to it, without littering the :external+py3.14:mod:`math` namespace. Now there are six functions and -:external+py3.14:func:`~math.factorial` doesn't accept :class:`float`'s +:external+py3.14:func:`~math.factorial` doesn't accept :class:`float`\ s anymore. Some possible additions, among those proposed in the initial discussion thread