Skip to content

Commit 37bc935

Browse files
miss-islingtonrhettinger
authored andcommitted
bpo-38237: Let pow() support keyword arguments (GH-16302) (GH-16320)
Backported with release manager approval
1 parent 865bb68 commit 37bc935

6 files changed

Lines changed: 73 additions & 49 deletions

File tree

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
@@ -1272,11 +1272,12 @@ are always available. They are listed here in alphabetical order.
12721272
returns ``8364``. This is the inverse of :func:`chr`.
12731273

12741274

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

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

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

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

12931295
Here's an example of computing an inverse for ``38`` modulo ``97``::
12941296

1295-
>>> pow(38, -1, 97)
1297+
>>> pow(38, -1, mod=97)
12961298
23
12971299
>>> 23 * 38 % 97 == 1
12981300
True
@@ -1302,6 +1304,10 @@ are always available. They are listed here in alphabetical order.
13021304
the second argument to be negative, permitting computation of modular
13031305
inverses.
13041306

1307+
.. versionchanged:: 3.9
1308+
Allow keyword arguments. Formerly, only positional arguments were
1309+
supported.
1310+
13051311

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

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
@@ -1797,22 +1797,22 @@ builtin_ord(PyObject *module, PyObject *c)
17971797
/*[clinic input]
17981798
pow as builtin_pow
17991799
1800-
x: object
1801-
y: object
1802-
z: object = None
1803-
/
1800+
base: object
1801+
exp: object
1802+
mod: object = None
18041803
1805-
Equivalent to x**y (with two arguments) or x**y % z (with three arguments)
1804+
Equivalent to base**exp (with two arguments) or base**exp % mod (with three arguments)
18061805
18071806
Some types, such as ints, are able to use a more efficient algorithm when
18081807
invoked using the three argument form.
18091808
[clinic start generated code]*/
18101809

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

18181818

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)