You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note that ternary pow() will not try calling rpow() (the coercion rules would become too complicated).
As far as I'm aware (I may be wrong!) ternary pow() is the only way that the modulo parameter can be passed to __pow__(). Since the documentation explicitly states that ternary pow() will not fall back on __rpow__(), it seems misleading that the summary for __rpow__() above contains the same optional modulo parameter as for __pow__().
Should the modulo parameter for __rpow__() be removed? Or are there some means other than ternary pow() by which this parameter can end up being passed to __rpow__()?
Third-party arithmetic libraries are free to implement the complicated coercion rules (or simplify them for their use case), and call __rpow__ directly.
And anyone who implements __rpow__ is free to raise an error if the third argument is unimplemented or doesn't make sense.
Third-party arithmetic libraries are free to implement the complicated coercion rules (or simplify them for their use case), and call __rpow__ directly.
Of course, they are free to do such (strange) things too. But that means they can't use python's arithmetic operators and builtin functions, e.g. ** or pow().
And anyone who implements __rpow__
Using Python dunder methods in such a library will be only a source of confusion. I would count such cases as library bugs.
On another hand, coercion rules for ternary ops in the CPython could be treated as an implementation details (and that should be clearly stated in docs). Different implementations may take other decisions here. Sorry, but I doubt that this case does make sense.
It seems, three-arg form __rpow__() does make sense for you, as you like Petr's comment. Could you elaborate this? There is no way to call this form indirectly (i.e. by pow()), only with an explicit call to this dunder. In that case I expect that people will use a dedicated public method instead. Or not?
Could you elaborate this? There is no way to call this form indirectly (i.e. by pow()), only with an explicit call to this dunder
At the time when I reacted with a 👍, I think this is what I had in mind.
In that case I expect that people will use a dedicated public method instead. Or not?
Yes and no I think. My reasoning was sa follows: it's possible to have some dispatcher mechanism, say
classInterface:
defrpow(self, x, mod=None):
# pre-validation of rpow()# then call the "fast" implementation directly.returnself.__rpow__(x, mod)
def__rpow__(self, x, mod=None):
# actual implementation of rpow()
...
From a design PoV, this could make sense to some users, where the dunder is the "fast & protected implementation, no redundant checks" while "rpow()" is the public method. So, even it our built-ins would never call __rpow__, someone might create an extended pow() function which does the job (and they would handle the coercion rules themselves, that's up to them). So, it's still make sense to allow the third argument, even if CPython itself doesn't use it.
I also think it's fine to keep identical input arguments for __pow__ and __rpow__. It's easier to remember one name and one list of parameters rather than "__pow__ has 3 arguments while __rpow__ has 2"
I think I mainly reacted 👍 to indicate that it's fine to keep a general form even though we don't use it ourselves.
even it our built-ins would never call __rpow__, someone might create an extended pow() function which does the job (and they would handle the coercion rules themselves, that's up to them).
This doesn't explain why someone will use poor dispatching mechanism, coming from Python, instead of proper multiple dispatch. And I guess nobody know real-world examples of this.
It's easier to remember one name and one list of parameters rather than "__pow__ has 3 arguments while __rpow__ has 2"
On another hand it's more difficult to remember semantics of __rpow__. If it has third argument, people will expect it to be passed in some scenario, which is not true.
Activity
skirpichev commentedon Jul 24, 2024
I don't think so.
pythongh-122193: simplify object.__rpow__() signature (no modulo)
encukou commentedon Jul 27, 2024
Third-party arithmetic libraries are free to implement the complicated coercion rules (or simplify them for their use case), and call
__rpow__directly.And anyone who implements
__rpow__is free to raise an error if the third argument is unimplemented or doesn't make sense.skirpichev commentedon Jul 27, 2024
@encukou, not sure I get your point.
Of course, they are free to do such (strange) things too. But that means they can't use python's arithmetic operators and builtin functions, e.g.
**orpow().Using Python dunder methods in such a library will be only a source of confusion. I would count such cases as library bugs.
On another hand, coercion rules for ternary ops in the CPython could be treated as an implementation details (and that should be clearly stated in docs). Different implementations may take other decisions here. Sorry, but I doubt that this case does make sense.
skirpichev commentedon Feb 14, 2025
CC @picnixz
It seems, three-arg form
__rpow__()does make sense for you, as you like Petr's comment. Could you elaborate this? There is no way to call this form indirectly (i.e. by pow()), only with an explicit call to this dunder. In that case I expect that people will use a dedicated public method instead. Or not?picnixz commentedon Feb 14, 2025
At the time when I reacted with a 👍, I think this is what I had in mind.
Yes and no I think. My reasoning was sa follows: it's possible to have some dispatcher mechanism, say
From a design PoV, this could make sense to some users, where the dunder is the "fast & protected implementation, no redundant checks" while "rpow()" is the public method. So, even it our built-ins would never call
__rpow__, someone might create an extendedpow()function which does the job (and they would handle the coercion rules themselves, that's up to them). So, it's still make sense to allow the third argument, even if CPython itself doesn't use it.I also think it's fine to keep identical input arguments for
__pow__and__rpow__. It's easier to remember one name and one list of parameters rather than "__pow__has 3 arguments while__rpow__has 2"I think I mainly reacted 👍 to indicate that it's fine to keep a general form even though we don't use it ourselves.
skirpichev commentedon Feb 15, 2025
This doesn't explain why someone will use poor dispatching mechanism, coming from Python, instead of proper multiple dispatch. And I guess nobody know real-world examples of this.
On another hand it's more difficult to remember semantics of
__rpow__. If it has third argument, people will expect it to be passed in some scenario, which is not true.skirpichev commentedon Feb 19, 2025
closing in favor of #130104