Issue38237
Created on 2019-09-20 17:21 by rhettinger, last changed 2020-03-27 16:45 by miss-islington. This issue is now closed.
| Pull Requests | |||
|---|---|---|---|
| URL | Status | Linked | Edit |
| PR 16302 | merged | ammar2, 2019-09-20 18:28 | |
| PR 16320 | merged | miss-islington, 2019-09-21 07:59 | |
| PR 16323 | merged | miss-islington, 2019-09-21 20:32 | |
| PR 19042 | merged | mark.dickinson, 2020-03-17 08:59 | |
| PR 19079 | merged | miss-islington, 2020-03-19 18:18 | |
| PR 19171 | merged | ammar2, 2020-03-26 05:38 | |
| PR 19192 | merged | miss-islington, 2020-03-27 16:38 | |
| Messages (28) | |||
|---|---|---|---|
| msg352876 - (view) | Author: Raymond Hettinger (rhettinger) * | Date: 2019-09-20 17:21 | |
Current signature:
pow(x, y, z=None, /)
Proposed signature:
pow(base, exp, mod=None)
Benefits:
* Meaningful and self-explanatory parameters in tooltips
* Optionally clearer calls for the three argument form:
pow(2, 5, mod=4)
* More usable with partial():
squared = partial(pow, exp=2)
|
|||
| msg352877 - (view) | Author: Ammar Askar (ammar2) * | Date: 2019-09-20 17:28 | |
Looks like a solid proposal, I especially like the clarity for the 3-argument call. Often beginners ask about why there's a third argument in pow especially when teaching RSA and number-theoretic stuff. Do you mind if I take this on Raymond? |
|||
| msg352878 - (view) | Author: Ammar Askar (ammar2) * | Date: 2019-09-20 17:59 | |
Actually quick question, should a similar change be made for `math.pow` for consistency's sake? |
|||
| msg352879 - (view) | Author: Ammar Askar (ammar2) * | Date: 2019-09-20 18:29 | |
I've made a PR, feel free to close it if you'd rather implement this yourself or this proposal won't be accepted :) |
|||
| msg352880 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2019-09-20 18:37 | |
You can use a lambda instead of partial:
squared = lambda x: pow(x, 2)
Proposed names look meaningful. But after adding support of keyword arguments please compare performance of the old and the new functions. I expect that the difference will be small, but we need to check.
|
|||
| msg352881 - (view) | Author: Ammar Askar (ammar2) * | Date: 2019-09-20 19:02 | |
Here's a little microbenchmark, let me know if there's anything specific you'd like to see: Before ====== > python -m pyperf timeit "from test.test_builtin import BuiltinTest; tst = BuiltinTest()" -- "tst.test_pow()" Mean +- std dev: 3.80 us +- 0.23 us > python -m pyperf timeit "pow(23, 19, 3)" Mean +- std dev: 519 ns +- 12 ns After ===== > python -m pyperf timeit "from test.test_builtin import BuiltinTest; tst = BuiltinTest()" -- "tst.test_pow()" Mean +- std dev: 3.80 us +- 0.26 us > python -m pyperf timeit "pow(23, 19, 3)" Mean +- std dev: 526 ns +- 18 ns |
|||
| msg352885 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2019-09-20 20:16 | |
The proposal sounds reasonable to me. > should a similar change be made for `math.pow` for consistency's sake? I'd leave math.pow alone here. |
|||
| msg352886 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2019-09-20 20:17 | |
Thank you. Could you please test simpler examples like pow(2, 3)? Please use the --duplicate option. |
|||
| msg352887 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2019-09-20 20:18 | |
And pow(2.0, 3.0) please. |
|||
| msg352895 - (view) | Author: Ammar Askar (ammar2) * | Date: 2019-09-20 21:29 | |
Before ====== >python -m pyperf timeit "pow(2, 3)" --duplicate 100000 Mean +- std dev: 242 ns +- 19 ns > python -m pyperf timeit "pow(2.0, 3.0)" --duplicate 100000 Mean +- std dev: 197 ns +- 16 ns After ===== > python -m pyperf timeit "pow(2, 3)" --duplicate 100000 Mean +- std dev: 243 ns +- 11 ns > python -m pyperf timeit "pow(2.0, 3.0)" --duplicate 100000 Mean +- std dev: 200 ns +- 14 ns |
|||
| msg352900 - (view) | Author: Ammar Askar (ammar2) * | Date: 2019-09-20 21:52 | |
math.pow changes removed from PR |
|||
| msg352923 - (view) | Author: miss-islington (miss-islington) | Date: 2019-09-21 04:28 | |
New changeset 87d6cd3604e5c83c06339276228139f5e040b0e7 by Miss Islington (bot) (Ammar Askar) in branch 'master': bpo-38237: Make pow's arguments have more descriptive names and be keyword passable (GH-16302) https://github.com/python/cpython/commit/87d6cd3604e5c83c06339276228139f5e040b0e7 |
|||
| msg352924 - (view) | Author: Raymond Hettinger (rhettinger) * | Date: 2019-09-21 04:29 | |
Thanks Ammar |
|||
| msg352927 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2019-09-21 05:54 | |
Thank you for your contribution Ammar! Nice work! |
|||
| msg352933 - (view) | Author: Raymond Hettinger (rhettinger) * | Date: 2019-09-21 08:22 | |
New changeset 37bc93552375cb1bc616927b5c1905bae3c0e99d by Raymond Hettinger (Miss Islington (bot)) in branch '3.8': bpo-38237: Let pow() support keyword arguments (GH-16302) (GH-16320) https://github.com/python/cpython/commit/37bc93552375cb1bc616927b5c1905bae3c0e99d |
|||
| msg352939 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2019-09-21 10:11 | |
Isn't it a new feature? Isn't it too later to add it to 3.8? |
|||
| msg352944 - (view) | Author: Raymond Hettinger (rhettinger) * | Date: 2019-09-21 16:50 | |
As noted in the checkin, this was backported with the release manager's assent. FWIW, pow() itself is an old feature, recently enhanced to support negative powers in a given modulus. When the enhancement went in, we should have done this as well. |
|||
| msg352951 - (view) | Author: Raymond Hettinger (rhettinger) * | Date: 2019-09-21 20:32 | |
New changeset 24231ca75c721c8167a7394deb300727ccdcba51 by Raymond Hettinger (Miss Islington (bot)) in branch '3.8': bpo-38237: Shorter docstring (GH-16322) (GH-16323) https://github.com/python/cpython/commit/24231ca75c721c8167a7394deb300727ccdcba51 |
|||
| msg352952 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2019-09-21 20:44 | |
Thank you for the explanation Raymond and sorry for the disturb. My mistake, I had not noticed the release manager's assent. |
|||
| msg364395 - (view) | Author: Berry Schoenmakers (lschoe) * | Date: 2020-03-17 08:32 | |
There seems to be a slight mixup with the built-in pow() function in Python 3.8.2. Currently, under https://docs.python.org/3/library/functions.html#pow it says: Changed in version 3.9: Allow keyword arguments. Formerly, only positional arguments were supported. I think this should be into "Changed in version 3.8 ... ", as pow(3,4, mod=5) actually works in Python 3.8.2. The "What’s New In Python 3.8" also needs to be changed accordingly. In https://docs.python.org/3/whatsnew/3.8.html#positional-only-parameters it says: One use case for this notation is that it allows pure Python functions to fully emulate behaviors of existing C coded functions. For example, the built-in pow() function does not accept keyword arguments: def pow(x, y, z=None, /): "Emulate the built in pow() function" r = x ** y return r if z is None else r%z This example can simply be dropped now. |
|||
| msg364396 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2020-03-17 09:03 | |
> This example can simply be dropped now. It could be, but it would be better to replace it with a different example that works. Any suggestions? |
|||
| msg364397 - (view) | Author: Ammar Askar (ammar2) * | Date: 2020-03-17 09:09 | |
In my original PR I changed it to divmod: https://github.com/python/cpython/pull/16302/files#diff-986275b975a33c44c0aba973362516fa |
|||
| msg364400 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2020-03-17 09:27 | |
It is hard to find a builtin which could be easy and clearly implemented in Python (it means no use of dunder methods). Maybe sorted()?
def sorted(iterable, /, *, key=None, reverse=False):
"""Emulate the built in sorted() function"""
result = list(iterable)
result.sort(key=key, reverse=reverse)
return result
Although I think that this use case is less important. The primary goal of the feature is mentioned at the end of the section -- easy way to implement functions which accept arbitrary keyword arguments.
|
|||
| msg364401 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2020-03-17 09:31 | |
divmod() should be implemented via __divmod__ and __rdivmod__. And they should be looked up on the type, not instance. There is no easy way to express it in Python accurately. This would make the example too complex. |
|||
| msg364402 - (view) | Author: Ammar Askar (ammar2) * | Date: 2020-03-17 09:42 | |
I don't think that matters. The example is supposed to just serve as an illustration, it doesn't need to encode the dunder dispatch semantics. The already existing example doesn't check for a __pow__. I'd picture it just as: return x//y, x%y |
|||
| msg364414 - (view) | Author: Berry Schoenmakers (lschoe) * | Date: 2020-03-17 11:50 | |
Maybe a use case in this direction: int(x, base=10).
Because, if you type
int(x='3', base=12)
you get
TypeError: 'x' is an invalid keyword argument for int()
and x needs to be a positional-only to program this yourself.
|
|||
| msg365166 - (view) | Author: Pablo Galindo Salgado (pablogsal) * | Date: 2020-03-27 16:37 | |
New changeset 5a58c5280b8df4ca5d6a19892b24fff96e9ea868 by Ammar Askar in branch 'master': bpo-38237: Use divmod for positional arguments whatsnew example (GH-19171) https://github.com/python/cpython/commit/5a58c5280b8df4ca5d6a19892b24fff96e9ea868 |
|||
| msg365167 - (view) | Author: miss-islington (miss-islington) | Date: 2020-03-27 16:45 | |
New changeset 9c5c497ac167b843089553f6f62437d263382e97 by Miss Islington (bot) in branch '3.8': bpo-38237: Use divmod for positional arguments whatsnew example (GH-19171) https://github.com/python/cpython/commit/9c5c497ac167b843089553f6f62437d263382e97 |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2020-03-27 16:45:09 | miss-islington | set | messages: + msg365167 |
| 2020-03-27 16:38:14 | miss-islington | set | pull_requests: + pull_request18552 |
| 2020-03-27 16:37:50 | pablogsal | set | nosy:
+ pablogsal messages: + msg365166 |
| 2020-03-26 05:38:59 | ammar2 | set | pull_requests: + pull_request18531 |
| 2020-03-19 18:18:29 | miss-islington | set | pull_requests: + pull_request18436 |
| 2020-03-17 11:50:58 | lschoe | set | messages: + msg364414 |
| 2020-03-17 09:42:57 | ammar2 | set | messages: + msg364402 |
| 2020-03-17 09:31:40 | serhiy.storchaka | set | messages: + msg364401 |
| 2020-03-17 09:27:49 | serhiy.storchaka | set | messages: + msg364400 |
| 2020-03-17 09:09:56 | ammar2 | set | messages: + msg364397 |
| 2020-03-17 09:03:41 | mark.dickinson | set | messages: + msg364396 |
| 2020-03-17 08:59:16 | mark.dickinson | set | pull_requests: + pull_request18393 |
| 2020-03-17 08:32:05 | lschoe | set | nosy:
+ lschoe messages: + msg364395 |
| 2019-09-21 20:44:01 | serhiy.storchaka | set | messages: + msg352952 |
| 2019-09-21 20:32:32 | miss-islington | set | pull_requests: + pull_request15901 |
| 2019-09-21 20:32:11 | rhettinger | set | messages: + msg352951 |
| 2019-09-21 16:50:01 | rhettinger | set | status: open -> closed messages:
+ msg352944 |
| 2019-09-21 10:11:28 | serhiy.storchaka | set | status: closed -> open nosy: + lukasz.langa messages: + msg352939 |
| 2019-09-21 08:22:37 | rhettinger | set | messages: + msg352933 |
| 2019-09-21 07:59:56 | miss-islington | set | pull_requests: + pull_request15897 |
| 2019-09-21 05:54:52 | serhiy.storchaka | set | messages: + msg352927 |
| 2019-09-21 04:29:31 | rhettinger | set | status: open -> closed resolution: fixed messages: + msg352924 stage: patch review -> resolved |
| 2019-09-21 04:28:53 | miss-islington | set | nosy:
+ miss-islington messages: + msg352923 |
| 2019-09-21 01:18:18 | rhettinger | set | assignee: rhettinger |
| 2019-09-20 21:52:49 | ammar2 | set | messages: + msg352900 |
| 2019-09-20 21:29:54 | ammar2 | set | messages: + msg352895 |
| 2019-09-20 20:18:57 | serhiy.storchaka | set | messages: + msg352887 |
| 2019-09-20 20:17:23 | serhiy.storchaka | set | messages: + msg352886 |
| 2019-09-20 20:16:14 | mark.dickinson | set | messages: + msg352885 |
| 2019-09-20 19:02:06 | ammar2 | set | messages: + msg352881 |
| 2019-09-20 18:37:05 | serhiy.storchaka | set | nosy:
+ serhiy.storchaka messages: + msg352880 |
| 2019-09-20 18:29:35 | ammar2 | set | messages: + msg352879 |
| 2019-09-20 18:28:49 | ammar2 | set | keywords:
+ patch stage: patch review pull_requests: + pull_request15887 |
| 2019-09-20 17:59:02 | ammar2 | set | messages: + msg352878 |
| 2019-09-20 17:28:14 | ammar2 | set | nosy:
+ ammar2 messages: + msg352877 |
| 2019-09-20 17:21:42 | rhettinger | create | |