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
|
|
Date |
User |
Action |
Args |
2022-04-11 14:59:20 | admin | set | github: 82418 |
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 versions:
+ Python 3.8 |
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 | |