Skip to content

Commit da9e7ed

Browse files
authored
Merge branch 'main' into warsaw/pep-772
2 parents 2f50c7a + 5625a11 commit da9e7ed

File tree

2 files changed

+185
-0
lines changed

2 files changed

+185
-0
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ peps/pep-0788.rst @ZeroIntensity @vstinner
669669
# ...
670670
peps/pep-0789.rst @njsmith
671671
peps/pep-0790.rst @hugovk
672+
peps/pep-0791.rst @vstinner
672673
# ...
673674
peps/pep-0801.rst @warsaw
674675
# ...

peps/pep-0791.rst

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
PEP: 791
2+
Title: imath --- module for integer-specific mathematics functions
3+
Author: Sergey B Kirpichev <skirpichev@gmail.com>
4+
Sponsor: Victor Stinner <vstinner@python.org>
5+
Discussions-To: https://discuss.python.org/t/92548
6+
Status: Draft
7+
Type: Standards Track
8+
Created: 12-May-2025
9+
Python-Version: 3.15
10+
Post-History: `12-Jul-2018 <https://mail.python.org/archives/list/python-ideas@python.org/thread/YYJ5YJBJNCVXQWK5K3WSVNMPUSV56LOR/>`__,
11+
02-Jun-2019,
12+
`09-May-2025 <https://discuss.python.org/t/91337>`__,
13+
`19-May-2025 <https://discuss.python.org/t/92548>`__,
14+
15+
16+
Abstract
17+
========
18+
19+
This PEP proposes a new module for number-theoretical, combinatorial and other
20+
functions defined for integer arguments, like
21+
:external+py3.14:func:`math.gcd` or :external+py3.14:func:`math.isqrt`.
22+
23+
24+
Motivation
25+
==========
26+
27+
The :external+py3.14:mod:`math` documentation says: "This module provides access
28+
to the mathematical functions defined by the C standard." But,
29+
over time the module was populated with functions that aren't related to
30+
the C standard or floating-point arithmetics. Now it's much harder to describe
31+
module scope, content and interfaces (returned values or accepted arguments).
32+
33+
For example, the :external+py3.14:mod:`math` module documentation says: "Except
34+
when explicitly noted otherwise, all return values are floats." This is no
35+
longer true: *None* of the functions listed in the `Number-theoretic
36+
functions <https://docs.python.org/3.14/library/math.html#number-theoretic-functions>`_
37+
subsection of the documentation return a float, but the
38+
documentation doesn't say so. In the documentation for the proposed ``imath`` module the sentence "All
39+
return values are integers." would be accurate. In a similar way we
40+
can simplify the description of the accepted arguments for functions in both the
41+
:external+py3.14:mod:`math` and the new module.
42+
43+
Apparently, the :external+py3.14:mod:`math` module can't serve as a catch-all place
44+
for mathematical functions since we also have the :external+py3.14:mod:`cmath` and
45+
:external+py3.14:mod:`statistics` modules. Let's do the same for integer-related
46+
functions. It provides shared context, which reduces verbosity in the
47+
documentation and conceptual load. It also aids discoverability through
48+
grouping related functions and makes IDE suggestions more helpful.
49+
50+
Currently the :external+py3.14:mod:`math` module code in the CPython is around
51+
4200LOC, from which the new module code is roughly 1/3 (1300LOC). This is
52+
comparable with the :external+py3.14:mod:`cmath` (1340LOC), which is *not* a
53+
simple wrapper to the ``libm``, as most functions in the
54+
:external+py3.14:mod:`math` module.
55+
56+
57+
Specification
58+
=============
59+
60+
The PEP proposes moving the following integer-related functions to a new
61+
module, called ``imath``:
62+
63+
* :external+py3.14:func:`~math.comb`
64+
* :external+py3.14:func:`~math.factorial`
65+
* :external+py3.14:func:`~math.gcd`
66+
* :external+py3.14:func:`~math.isqrt`
67+
* :external+py3.14:func:`~math.lcm`
68+
* :external+py3.14:func:`~math.perm`
69+
70+
Their aliases in :external+py3.14:mod:`math` will be :term:`soft deprecated`.
71+
72+
Module functions will accept integers and objects that implement the
73+
:external+py3.14:meth:`~object.__index__` method, which is used to convert the
74+
object to an integer number. Suitable functions must be computed exactly,
75+
given sufficient time and memory.
76+
77+
Possible extensions for the new module and its scope are discussed in the
78+
`Open Issues <Open Issues_>`_ section. New functions are not part of this
79+
proposal.
80+
81+
82+
Backwards Compatibility
83+
=======================
84+
85+
As aliases in :external+py3.14:mod:`math` will be kept for an indefinite time
86+
(their use would be discouraged), there are no anticipated code breaks.
87+
88+
89+
How to Teach This
90+
=================
91+
92+
The new module will be a place for functions, that 1) accept
93+
:external+py3.14:class:`int`-like arguments and also return integers, and 2) are
94+
also in the field of arbitrary-precision integer arithmetic, i.e. have no
95+
dependency on the platform floating-point format or behaviour and/or on the
96+
platform math library (``libm``).
97+
98+
For users it would be natural first to look on the
99+
:external+py3.14:class:`int`'s methods, which cover most basic use-cases (e.g.
100+
:external+py3.14:meth:`int.bit_length` method), than to some dedicated place in
101+
the stdlib.
102+
103+
104+
Reference Implementation
105+
========================
106+
107+
`python/cpython#133909 <https://github.com/python/cpython/pull/133909>`_
108+
109+
110+
Open Issues
111+
===========
112+
113+
Module name
114+
-----------
115+
116+
The chosen name seems consistent with one existing domain-specific mathematical module:
117+
:external+py3.14:mod:`cmath` (for complex numbers).
118+
119+
We note the `Imath
120+
<https://github.com/AcademySoftwareFoundation/Imath>`_ C++ library includes
121+
Python bindings with the same name. There is also an :pypi:`imath` project on
122+
PyPI, but only with two releases, with the most recent one four years ago. Its
123+
repository is no longer accessible.
124+
125+
`Polling showed <https://discuss.python.org/t/91337/35>`_ ``intmath`` as another
126+
popular name. The argument made was that the normal mathematical spelling of
127+
the imaginary unit is ``i``, which makes ``imath`` ambiguous. It also has no conflict
128+
with any PyPI module. On the other hand, ``intmath`` may be confused with
129+
interval math or numerical integration.
130+
131+
Other proposed names include ``ntheory`` (like SymPy's submodule),
132+
``integermath`` and ``imaths``.
133+
134+
135+
Module scope and possible extensions
136+
------------------------------------
137+
138+
Unless we can just provide bindings to some well supported mathematical library
139+
like the GMP, the module scope should be limited. For example, no primality
140+
testing and factorization, as production-quality implementatons will require a
141+
decent mathematical background from contributors and belongs rather to
142+
specialized libraries.
143+
144+
Some possible additions, among those proposed in the initial discussion thread
145+
(see also issue
146+
`python/cpython#81313 <https://github.com/python/cpython/issues/81313>`_):
147+
148+
* ``ceil_div()`` --- for integer ceiling divide, see
149+
`relevant discussion thread <https://discuss.python.org/t/91269>`_.
150+
* ``gcdext()`` --- to solve linear `Diophantine equation <https://en.wikipedia.org/wiki/Diophantine_equation>`_ in two variables (the
151+
:external+py3.14:class:`int` implementation actually includes an extended
152+
Euclidean algorithm)
153+
* ``isqrt_rem()`` --- to return both an integer square root and a remainder (which is non-zero only if
154+
the integer isn't a perfect square)
155+
* ``ilog()`` --- integer logarithm, :external+py3.14:func:`math.log`
156+
has special handling for integer arguments. It's unique (with respect to other module
157+
functions) and not documented so far, see issue
158+
`python/cpython#120950 <https://github.com/python/cpython/issues/120950>`_.
159+
* ``fibonacci()`` --- `Fibonacci sequence <https://en.wikipedia.org/wiki/Fibonacci_sequence>`_.
160+
161+
162+
Rejected ideas
163+
==============
164+
165+
There was a brief discussion about exposing :external+py3.14:func:`math.isqrt`
166+
as ``imath.sqrt`` in the same way that :external+py3.14:func:`cmath.sqrt` is
167+
the complex version of :external+py3.14:func:`math.sqrt`. However, ``isqrt``
168+
is ultimately a different function: it is the floor of the square root. It
169+
would be confusing to give it the same name (under a different module).
170+
171+
172+
Acknowledgements
173+
================
174+
175+
Thanks to Tim Peters for reviving the idea of splitting the :external+py3.14:mod:`math`
176+
module. Thanks to Neil Girdhar for substantial improvements of
177+
the initial draft.
178+
179+
180+
Copyright
181+
=========
182+
183+
This document is placed in the public domain or under the
184+
CC0-1.0-Universal license, whichever is more permissive.

0 commit comments

Comments
 (0)