Skip to content

Commit 1a58499

Browse files
skirpichevhugovkvstinnerhoodmaneefimov-mikhail
authored
PEP 791: imath --- module for integer-specific mathematics functions (#4422)
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Victor Stinner <vstinner@python.org> Co-authored-by: Hood Chatham <roberthoodchatham@gmail.com> Co-authored-by: Mikhail Efimov <efimov.mikhail@gmail.com> Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Co-authored-by: Neil Girdhar <mistersheik@gmail.com>
1 parent 8a7de2f commit 1a58499

File tree

2 files changed

+184
-0
lines changed

2 files changed

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

0 commit comments

Comments
 (0)