Skip to content

Commit

Permalink
bpo-38237: Make pow's arguments have more descriptive names and be ke…
Browse files Browse the repository at this point in the history
…yword passable (pythonGH-16302)

Edit: `math.pow` changes removed on Mark's request.


https://bugs.python.org/issue38237



Automerge-Triggered-By: @rhettinger
  • Loading branch information
ammaraskar authored and miss-islington committed Sep 21, 2019
1 parent e267793 commit 87d6cd3
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 49 deletions.
25 changes: 11 additions & 14 deletions Doc/faq/programming.rst
Original file line number Diff line number Diff line change
Expand Up @@ -779,26 +779,23 @@ A slash in the argument list of a function denotes that the parameters prior to
it are positional-only. Positional-only parameters are the ones without an
externally-usable name. Upon calling a function that accepts positional-only
parameters, arguments are mapped to parameters based solely on their position.
For example, :func:`pow` is a function that accepts positional-only parameters.
Its documentation looks like this::
For example, :func:`divmod` is a function that accepts positional-only
parameters. Its documentation looks like this::

>>> help(pow)
Help on built-in function pow in module builtins:
>>> help(divmod)
Help on built-in function divmod in module builtins:

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

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

The slash at the end of the parameter list means that all three parameters are
positional-only. Thus, calling :func:`pow` with keyword arguments would lead to
an error::

>>> pow(x=3, y=4)
>>> divmod(x=3, y=4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pow() takes no keyword arguments
TypeError: divmod() takes no keyword arguments


Numbers and strings
Expand Down
24 changes: 15 additions & 9 deletions Doc/library/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1274,11 +1274,12 @@ are always available. They are listed here in alphabetical order.
returns ``8364``. This is the inverse of :func:`chr`.


.. function:: pow(x, y[, z])
.. function:: pow(base, exp[, mod])

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

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

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

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

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

.. versionchanged:: 3.9
Allow keyword arguments. Formerly, only positional arguments were
supported.


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

Expand Down
13 changes: 13 additions & 0 deletions Lib/test/test_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import unittest
import warnings
from contextlib import ExitStack
from functools import partial
from inspect import CO_COROUTINE
from itertools import product
from textwrap import dedent
Expand Down Expand Up @@ -1206,6 +1207,18 @@ def test_pow(self):

self.assertRaises(TypeError, pow)

# Test passing in arguments as keywords.
self.assertEqual(pow(0, exp=0), 1)
self.assertEqual(pow(base=2, exp=4), 16)
self.assertEqual(pow(base=5, exp=2, mod=14), 11)
twopow = partial(pow, base=2)
self.assertEqual(twopow(exp=5), 32)
fifth_power = partial(pow, exp=5)
self.assertEqual(fifth_power(2), 32)
mod10 = partial(pow, mod=10)
self.assertEqual(mod10(2, 6), 4)
self.assertEqual(mod10(exp=6, base=2), 4)

def test_input(self):
self.write_testfile()
fp = open(TESTFN, 'r')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The arguments for the builtin pow function are more descriptive. They can now
also be passed in as keywords.
16 changes: 8 additions & 8 deletions Python/bltinmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1796,22 +1796,22 @@ builtin_ord(PyObject *module, PyObject *c)
/*[clinic input]
pow as builtin_pow
x: object
y: object
z: object = None
/
base: object
exp: object
mod: object = None
Equivalent to x**y (with two arguments) or x**y % z (with three arguments)
Equivalent to base**exp (with two arguments) or base**exp % mod (with three arguments)
Some types, such as ints, are able to use a more efficient algorithm when
invoked using the three argument form.
[clinic start generated code]*/

static PyObject *
builtin_pow_impl(PyObject *module, PyObject *x, PyObject *y, PyObject *z)
/*[clinic end generated code: output=50a14d5d130d404b input=653d57d38d41fc07]*/
builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp,
PyObject *mod)
/*[clinic end generated code: output=3ca1538221bbf15f input=bd72d0a0ec8e5eb5]*/
{
return PyNumber_Power(x, y, z);
return PyNumber_Power(base, exp, mod);
}


Expand Down
42 changes: 24 additions & 18 deletions Python/clinic/bltinmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 87d6cd3

Please sign in to comment.