Skip to content

Commit 87d6cd3

Browse files
ammaraskarmiss-islington
authored andcommitted
bpo-38237: Make pow's arguments have more descriptive names and be keyword passable (GH-16302)
Edit: `math.pow` changes removed on Mark's request. https://bugs.python.org/issue38237 Automerge-Triggered-By: @rhettinger
1 parent e267793 commit 87d6cd3

File tree

6 files changed

+73
-49
lines changed

6 files changed

+73
-49
lines changed

Doc/faq/programming.rst

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -779,26 +779,23 @@ A slash in the argument list of a function denotes that the parameters prior to
779779
it are positional-only. Positional-only parameters are the ones without an
780780
externally-usable name. Upon calling a function that accepts positional-only
781781
parameters, arguments are mapped to parameters based solely on their position.
782-
For example, :func:`pow` is a function that accepts positional-only parameters.
783-
Its documentation looks like this::
782+
For example, :func:`divmod` is a function that accepts positional-only
783+
parameters. Its documentation looks like this::
784784

785-
>>> help(pow)
786-
Help on built-in function pow in module builtins:
785+
>>> help(divmod)
786+
Help on built-in function divmod in module builtins:
787787

788-
pow(x, y, z=None, /)
789-
Equivalent to x**y (with two arguments) or x**y % z (with three arguments)
788+
divmod(x, y, /)
789+
Return the tuple (x//y, x%y). Invariant: div*y + mod == x.
790790

791-
Some types, such as ints, are able to use a more efficient algorithm when
792-
invoked using the three argument form.
791+
The slash at the end of the parameter list means that both parameters are
792+
positional-only. Thus, calling :func:`divmod` with keyword arguments would lead
793+
to an error::
793794

794-
The slash at the end of the parameter list means that all three parameters are
795-
positional-only. Thus, calling :func:`pow` with keyword arguments would lead to
796-
an error::
797-
798-
>>> pow(x=3, y=4)
795+
>>> divmod(x=3, y=4)
799796
Traceback (most recent call last):
800797
File "<stdin>", line 1, in <module>
801-
TypeError: pow() takes no keyword arguments
798+
TypeError: divmod() takes no keyword arguments
802799

803800

804801
Numbers and strings

Doc/library/functions.rst

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,11 +1274,12 @@ are always available. They are listed here in alphabetical order.
12741274
returns ``8364``. This is the inverse of :func:`chr`.
12751275

12761276

1277-
.. function:: pow(x, y[, z])
1277+
.. function:: pow(base, exp[, mod])
12781278

1279-
Return *x* to the power *y*; if *z* is present, return *x* to the power *y*,
1280-
modulo *z* (computed more efficiently than ``pow(x, y) % z``). The two-argument
1281-
form ``pow(x, y)`` is equivalent to using the power operator: ``x**y``.
1279+
Return *base* to the power *exp*; if *mod* is present, return *base* to the
1280+
power *exp*, modulo *mod* (computed more efficiently than
1281+
``pow(base, exp) % mod``). The two-argument form ``pow(base, exp)`` is
1282+
equivalent to using the power operator: ``base**exp``.
12821283

12831284
The arguments must have numeric types. With mixed operand types, the
12841285
coercion rules for binary arithmetic operators apply. For :class:`int`
@@ -1287,14 +1288,15 @@ are always available. They are listed here in alphabetical order.
12871288
converted to float and a float result is delivered. For example, ``10**2``
12881289
returns ``100``, but ``10**-2`` returns ``0.01``.
12891290

1290-
For :class:`int` operands *x* and *y*, if *z* is present, *z* must also be
1291-
of integer type and *z* must be nonzero. If *z* is present and *y* is
1292-
negative, *x* must be relatively prime to *z*. In that case, ``pow(inv_x,
1293-
-y, z)`` is returned, where *inv_x* is an inverse to *x* modulo *z*.
1291+
For :class:`int` operands *base* and *exp*, if *mod* is present, *mod* must
1292+
also be of integer type and *mod* must be nonzero. If *mod* is present and
1293+
*exp* is negative, *base* must be relatively prime to *mod*. In that case,
1294+
``pow(inv_base, -exp, mod)`` is returned, where *inv_base* is an inverse to
1295+
*base* modulo *mod*.
12941296

12951297
Here's an example of computing an inverse for ``38`` modulo ``97``::
12961298

1297-
>>> pow(38, -1, 97)
1299+
>>> pow(38, -1, mod=97)
12981300
23
12991301
>>> 23 * 38 % 97 == 1
13001302
True
@@ -1304,6 +1306,10 @@ are always available. They are listed here in alphabetical order.
13041306
the second argument to be negative, permitting computation of modular
13051307
inverses.
13061308

1309+
.. versionchanged:: 3.9
1310+
Allow keyword arguments. Formerly, only positional arguments were
1311+
supported.
1312+
13071313

13081314
.. function:: print(*objects, sep=' ', end='\\n', file=sys.stdout, flush=False)
13091315

Lib/test/test_builtin.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import unittest
2020
import warnings
2121
from contextlib import ExitStack
22+
from functools import partial
2223
from inspect import CO_COROUTINE
2324
from itertools import product
2425
from textwrap import dedent
@@ -1206,6 +1207,18 @@ def test_pow(self):
12061207

12071208
self.assertRaises(TypeError, pow)
12081209

1210+
# Test passing in arguments as keywords.
1211+
self.assertEqual(pow(0, exp=0), 1)
1212+
self.assertEqual(pow(base=2, exp=4), 16)
1213+
self.assertEqual(pow(base=5, exp=2, mod=14), 11)
1214+
twopow = partial(pow, base=2)
1215+
self.assertEqual(twopow(exp=5), 32)
1216+
fifth_power = partial(pow, exp=5)
1217+
self.assertEqual(fifth_power(2), 32)
1218+
mod10 = partial(pow, mod=10)
1219+
self.assertEqual(mod10(2, 6), 4)
1220+
self.assertEqual(mod10(exp=6, base=2), 4)
1221+
12091222
def test_input(self):
12101223
self.write_testfile()
12111224
fp = open(TESTFN, 'r')
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The arguments for the builtin pow function are more descriptive. They can now
2+
also be passed in as keywords.

Python/bltinmodule.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,22 +1796,22 @@ builtin_ord(PyObject *module, PyObject *c)
17961796
/*[clinic input]
17971797
pow as builtin_pow
17981798
1799-
x: object
1800-
y: object
1801-
z: object = None
1802-
/
1799+
base: object
1800+
exp: object
1801+
mod: object = None
18031802
1804-
Equivalent to x**y (with two arguments) or x**y % z (with three arguments)
1803+
Equivalent to base**exp (with two arguments) or base**exp % mod (with three arguments)
18051804
18061805
Some types, such as ints, are able to use a more efficient algorithm when
18071806
invoked using the three argument form.
18081807
[clinic start generated code]*/
18091808

18101809
static PyObject *
1811-
builtin_pow_impl(PyObject *module, PyObject *x, PyObject *y, PyObject *z)
1812-
/*[clinic end generated code: output=50a14d5d130d404b input=653d57d38d41fc07]*/
1810+
builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp,
1811+
PyObject *mod)
1812+
/*[clinic end generated code: output=3ca1538221bbf15f input=bd72d0a0ec8e5eb5]*/
18131813
{
1814-
return PyNumber_Power(x, y, z);
1814+
return PyNumber_Power(base, exp, mod);
18151815
}
18161816

18171817

Python/clinic/bltinmodule.c.h

Lines changed: 24 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)