Skip to content

Commit 849338f

Browse files
committed
PEP 791: imath --- module for number-theoretic functions
1 parent 166ddce commit 849338f

File tree

2 files changed

+166
-0
lines changed

2 files changed

+166
-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: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
PEP: 791
2+
Title: imath --- module for number-theoretic 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: 10-May-2025
9+
Python-Version: 3.15
10+
Post-History: 02-Jun-2019,
11+
`09-May-2025 <https://discuss.python.org/t/91337>`__,
12+
13+
14+
Abstract
15+
========
16+
17+
This PEP proposes a new module for number-theoretical, combinatorial and other
18+
integer-valued functions defined for integer arguments, like
19+
:external+py3.14:func:`math.gcd` or :external+py3.14:func:`math.isqrt`.
20+
21+
22+
Motivation
23+
==========
24+
25+
The :external+py3.14:mod:`math` documentation says: "This module provides access
26+
to the mathematical functions defined by the C standard." But as a state of
27+
art, over time the module was populated with functions that aren't related to
28+
the C standard or floating-point arithmetics. Now it's much harder to describe
29+
module scope, content and interfaces (returned values or accepted arguments).
30+
31+
For example, the :external+py3.14:mod:`math` module documentation says: "Except
32+
when explicitly noted otherwise, all return values are floats." This is not
33+
longer true: *None* of the functions listed in the "Number-theoretic
34+
functions" [1]_ subsection of the documentation returns a float, but the
35+
documentation doesn't say so. In the proposed module a similar sentence "All
36+
return values are integers." could tell the truth once. In a similar way we
37+
can simplify description of accepted arguments for both the
38+
:external+py3.14:mod:`math` and the new module.
39+
40+
Apparently, the :external+py3.14:mod:`math` can't serve as a catch-all place
41+
for mathematical functions: we have also the :external+py3.14:mod:`cmath` and
42+
the :external+py3.14:mod:`statistics`. Let's make same for integer-related
43+
functions. It would provide shared context, which reduces verbosity in the
44+
documentation and conceptual load. It also aids discoverability through
45+
grouping related functions and IDEs suggesting helpful completions.
46+
47+
48+
Specification
49+
=============
50+
51+
The PEP proposes moving the following integer-related functions [1]_ in a new
52+
module, called ``imath``:
53+
54+
* :external+py3.14:func:`~math.comb`
55+
* :external+py3.14:func:`~math.factorial`
56+
* :external+py3.14:func:`~math.gcd`
57+
* :external+py3.14:func:`~math.isqrt`
58+
* :external+py3.14:func:`~math.lcm`
59+
* :external+py3.14:func:`~math.perm`
60+
61+
Their aliases in :external+py3.14:mod:`math` will be :term:`soft deprecated`.
62+
63+
Modules functions will accept integers and objects that implement the
64+
:external+py3.14:meth:`~object.__index__` method which is used to convert the
65+
object to an integer number.
66+
67+
Possible extensions for the new module and it's scope are discussed in the
68+
`Open Issues <Open Issues_>`_ section. New functions are not part of the
69+
proposal.
70+
71+
72+
Backwards Compatibility
73+
=======================
74+
75+
As aliases in :external+py3.14:mod:`math` will be kept for indefinite time
76+
(their use would be discouraged), there are no anticipated code breaks.
77+
78+
79+
Reference Implementation
80+
========================
81+
82+
https://github.com/python/cpython/pull/133909
83+
84+
85+
Open Issues
86+
===========
87+
88+
Module name
89+
-----------
90+
91+
Chosen name seems consistent with other domain-specific mathematical module:
92+
:external+py3.14:mod:`cmath` (for complex numbers).
93+
94+
There is already an ``imath`` project on PyPI, but only with two releases, with
95+
the most recent one 4 years ago. Its repository is no longer accessible.
96+
The `Imath <https://github.com/AcademySoftwareFoundation/Imath>`_ C++ library
97+
include Python bindings with same name.
98+
99+
`Polling shows <https://discuss.python.org/t/91337/35>`_ ``intmath`` as another
100+
popular name. The argument made was that the normal mathematical spelling of
101+
the imaginary unit is ``i``, which makes imath ambiguous. It also has no conflict
102+
with any PyPI module. On the other hand, ``intmath`` may be confused with
103+
interval math or numerical integration.
104+
105+
Other proposed names include ``ntheory`` (like SymPy's submodule),
106+
``integermath`` and ``imaths``.
107+
108+
109+
Module scope and possible extensions
110+
------------------------------------
111+
112+
Unless we can just provide bindings to some well supported mathematical library
113+
like the GMP, the module scope should be limited. For example, no primality
114+
testing and factorization.
115+
116+
There are possible additions, among proposed in the initial discussion thread
117+
(see also [5]_):
118+
119+
* ``c_div()`` --- for integer ceiling divide, see [2]_, [3]_.
120+
* ``gcdext()`` --- to solve linear Diophantine equation in two variables (the
121+
:external+py3.14:class:`int` implementation actually include extended
122+
Euclidean algorithm)
123+
* ``isqrt_rem()`` --- to return both integer square root and a remainder (if
124+
integer isn't a perfect square)
125+
* ``ilog()`` --- integer logarithm, currently :external+py3.14:func:`math.log`
126+
has a special handling for integer arguments. It's unique (wrt other module
127+
functions) and not documented so far, see [4]_
128+
* ``fibonacci()``.
129+
130+
131+
Rejected ideas
132+
==============
133+
134+
There was a brief discussion about exposing :external+py3.14:func:`math.isqrt`
135+
as ``imath.sqrt`` in the same way that :external+py3.14:func:`cmath.sqrt` is
136+
the complex version of :external+py3.14:func:`math.sqrt`. However, ``isqrt``
137+
is ultimately a different function: it is the floor of the square root. It
138+
would be confusing to give it the same name (under a different module).
139+
140+
141+
Acknowledgements
142+
================
143+
144+
Thanks to Tim Peters for reviving the idea of the :external+py3.14:mod:`math`
145+
splitting. Thanks to Neil Girdhar for substantial improvements of
146+
the initial draft.
147+
148+
149+
Footnotes
150+
=========
151+
152+
.. [1] Number-theoretic functions
153+
(https://docs.python.org/3.14/library/math.html#number-theoretic-functions)
154+
.. [2] Integer ceiling divide
155+
(https://discuss.python.org/t/91269)
156+
.. [3] https://gmpy2.readthedocs.io/en/stable/mpz.html#gmpy2.c_div
157+
.. [4] https://github.com/python/cpython/issues/120950
158+
.. [5] https://github.com/python/cpython/issues/81313
159+
160+
161+
Copyright
162+
=========
163+
164+
This document is placed in the public domain or under the
165+
CC0-1.0-Universal license, whichever is more permissive.

0 commit comments

Comments
 (0)