This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: PyNumber_InPlacePower ignores o3 if o1 implements __ipow__
Type: behavior Stage:
Components: C API Versions: Python 3.10, Python 3.9, Python 3.8, Python 3.7, Python 3.6, Python 3.5
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: ammar2, brett.cannon, hodgestar
Priority: normal Keywords:

Created on 2020-10-01 15:10 by hodgestar, last changed 2022-04-11 14:59 by admin.

Messages (5)
msg377758 - (view) Author: Simon Cross (hodgestar) Date: 2020-10-01 15:10
The documentation for PyNumber_InPlacePower [1] reads:

This is the equivalent of the Python statement o1 **= o2 when o3 is Py_None, or an in-place variant of pow(o1, o2, o3) otherwise. If o3 is to be ignored, pass Py_None in its place (passing NULL for o3 would cause an illegal memory access).

However, if a class A implements __ipow__ then PyNumber_InPlacePower(o1, o2, o3) ALWAYS ignores o3 if o1 is an instance of A.

This happens because if A implements __ipow__ then PyNumber_InPlacePower always calls the nb_inplace_power slot [2] and the slot always drops the third argument [3].

This appears to have always been the case in Python, so likely a small documentation patch is all that is required. If people agree, I will open a documentation pull request.

[1] https://docs.python.org/3/c-api/number.html?highlight=pynumber_inplacepower#c.PyNumber_InPlacePower

[2] https://github.com/python/cpython/blob/master/Objects/abstract.c#L1164

[3] https://github.com/python/cpython/blob/master/Objects/typeobject.c#L6631-L6636
msg377760 - (view) Author: Simon Cross (hodgestar) Date: 2020-10-01 15:14
The documentation for __ipow__ [4] suggests that the intention was to support the modulus argument, so perhaps that argues for fixing the behaviour of PyNumber_InPlacePower.

[4] https://docs.python.org/3/reference/datamodel.html#object.__ipow__
msg377761 - (view) Author: Ammar Askar (ammar2) * (Python committer) Date: 2020-10-01 15:20
Huh, this is weird. I wonder why the data model provides the signature

  object.__ipow__(self, other[, modulo])

if the slot always seems to drop the third argument.

Adding Brett to the nosy who found another issue around the special casing of pow/** recently. See also issue38302
msg377766 - (view) Author: Ammar Askar (ammar2) * (Python committer) Date: 2020-10-01 15:46
Also of note, there is actually no way to call `PyNumber_InPlacePower` from pure python from what I can tell. Even libraries like numpy don't implement the three-argument version of the nb_inplace_power slot.
msg377767 - (view) Author: Ammar Askar (ammar2) * (Python committer) Date: 2020-10-01 15:48
Whoops, forgot the numpy link: https://github.com/numpy/numpy/blob/33e1dbee8d9e11a3e96efaae822ff6f3c44e3cef/numpy/core/src/multiarray/number.c#L729-L741
History
Date User Action Args
2022-04-11 14:59:36adminsetgithub: 86069
2020-10-01 15:48:52ammar2setmessages: + msg377767
2020-10-01 15:46:29ammar2setmessages: + msg377766
2020-10-01 15:20:28ammar2setnosy: + brett.cannon
2020-10-01 15:20:21ammar2setnosy: + ammar2
messages: + msg377761
2020-10-01 15:14:53hodgestarsetmessages: + msg377760
2020-10-01 15:10:02hodgestarcreate