python / cpython

The Python programming language
https://www.python.org
Other
63.51k stars 30.42k forks source link

Should `__rpow__()` take `modulo` argument? #122193

Open Cartroo opened 3 months ago

Cartroo commented 3 months ago

Documentation

The documentation for __rpow__() clearly states:

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__()?

Linked PRs

skirpichev commented 3 months ago

Or are there some means other than ternary pow() by which this parameter can end up being passed to rpow()?

I don't think so.

encukou commented 3 months ago

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 commented 3 months ago

@encukou, not sure I get your point.

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.