From 3eb69adf09ac6240552a633178756fc40cccd876 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 17 Feb 2025 15:04:29 +0200 Subject: [PATCH 1/3] gh-86069: Do not ignore the third argument in slot_nb_inplace_power() The default implementation of the nb_inplace_power slot no longer ignores the third argument, but passes it to the __ipow__ method if its value is not None. --- Lib/test/test_capi/test_number.py | 3 +-- .../2025-02-17-15-04-19.gh-issue-86069.qeWCJF.rst | 4 ++++ Objects/typeobject.c | 10 ++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-04-19.gh-issue-86069.qeWCJF.rst diff --git a/Lib/test/test_capi/test_number.py b/Lib/test/test_capi/test_number.py index b915dee37c7ca6..bd3f96f2452a26 100644 --- a/Lib/test/test_capi/test_number.py +++ b/Lib/test/test_capi/test_number.py @@ -248,8 +248,7 @@ def __ipow__(*args): x = X() self.assertEqual(inplacepower(x, 11), (x, 11)) - # XXX: In-place power doesn't pass the third arg to __ipow__. - self.assertEqual(inplacepower(x, 11, 5), (x, 11)) + self.assertEqual(inplacepower(x, 11, 5), (x, 11, 5)) def test_long(self): # Test PyNumber_Long() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-04-19.gh-issue-86069.qeWCJF.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-04-19.gh-issue-86069.qeWCJF.rst new file mode 100644 index 00000000000000..e67e557f9b5dc8 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-04-19.gh-issue-86069.qeWCJF.rst @@ -0,0 +1,4 @@ +The default implementation of the +:c:member:`~PyNumberMethods.nb_inplace_power` slot no longer ignores the +third argument, but passes it to the :meth:`~object.__ipow__` method if its +value is not ``None``. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1fa1220aeec648..dee2df37ce0d63 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -9907,8 +9907,14 @@ SLOT1(slot_nb_inplace_remainder, __imod__, PyObject *) static PyObject * slot_nb_inplace_power(PyObject *self, PyObject * arg1, PyObject *arg2) { - PyObject *stack[2] = {self, arg1}; - return vectorcall_method(&_Py_ID(__ipow__), stack, 2); + if (arg2 == Py_None) { + PyObject *stack[2] = {self, arg1}; + return vectorcall_method(&_Py_ID(__ipow__), stack, 2); + } + else { + PyObject *stack[3] = {self, arg1, arg2}; + return vectorcall_method(&_Py_ID(__ipow__), stack, 3); + } } SLOT1(slot_nb_inplace_lshift, __ilshift__, PyObject *) SLOT1(slot_nb_inplace_rshift, __irshift__, PyObject *) From 0fe3047602b33c89d1f91b2fbdcfabbb3ddff1f4 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 18 Feb 2025 10:59:54 +0200 Subject: [PATCH 2/3] Update documentation. --- Doc/c-api/number.rst | 5 +++-- Doc/reference/datamodel.rst | 7 +++++++ Doc/whatsnew/3.14.rst | 6 ++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst index ad8b5935258fa7..0438869d9bf7fb 100644 --- a/Doc/c-api/number.rst +++ b/Doc/c-api/number.rst @@ -196,8 +196,9 @@ Number Protocol See the built-in function :func:`pow`. Returns ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python - statement ``o1 **= o2`` when o3 is :c:data:`Py_None`, or an in-place variant of - ``pow(o1, o2, o3)`` otherwise. If *o3* is to be ignored, pass :c:data:`Py_None` + statement ``o1 **= o2`` when o3 is :c:data:`Py_None`, or hypothetical in-place variant of + ``pow(o1, o2, o3)`` (not supported in Python) otherwise. + If *o3* is to be ignored, pass :c:data:`Py_None` in its place (passing ``NULL`` for *o3* would cause an illegal memory access). diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 66b836eaf0008a..614db259ee4748 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -3398,6 +3398,13 @@ left undefined. :ref:`faq-augmented-assignment-tuple-error`), but this behavior is in fact part of the data model. + Note that :meth:`__ipow__` should be defined to accept an optional third + argument if the third non-``None`` argument of + :c:func:`PyNumber_InPlacePower` is to be supported. + + .. versionchanged:: next + :meth:`!__ipow__` can now be called with three arguments in + :c:func:`!PyNumber_InPlacePower`. .. method:: object.__neg__(self) object.__pos__(self) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index ac0ae8cf0133e6..0b7d1b06f868be 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -307,6 +307,12 @@ Other language changes The testbed can also be used to run the test suite of projects other than CPython itself. (Contributed by Russell Keith-Magee in :gh:`127592`.) +* The :meth:`~object.__ipow__` method should be defined to accept an optional + third argument (as it was documented) to support non-``None`` third argument + in :c:func:`PyNumber_InPlacePower` which no longer ignored if + :meth:`!__ipow__` is defined. + (Contributed by Serhiy Storchaka in :gh:`86069`.) + New modules =========== From 25df365c4930c41efa7c61c6d1aaa34e12358597 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 8 May 2025 21:35:03 +0300 Subject: [PATCH 3/3] Move to 3.15. --- Doc/whatsnew/3.14.rst | 6 ------ Doc/whatsnew/3.15.rst | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 9bc58b0e896c37..894f011ec86a30 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -898,12 +898,6 @@ Other language changes binary power operator. (Contributed by Serhiy Storchaka in :gh:`130104`.) -* The :meth:`~object.__ipow__` method should be defined to accept an optional - third argument (as it was documented) to support non-``None`` third argument - in :c:func:`PyNumber_InPlacePower` which no longer ignored if - :meth:`!__ipow__` is defined. - (Contributed by Serhiy Storchaka in :gh:`86069`.) - * Add a built-in implementation for HMAC (:rfc:`2104`) using formally verified code from the `HACL* `__ project. This implementation is used as a fallback when the OpenSSL implementation diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 7131eeb697eb69..a0a3a73e2e7a41 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -75,6 +75,11 @@ New features Other language changes ====================== +* The :meth:`~object.__ipow__` method should be defined to accept an optional + third argument (as it was documented) to support non-``None`` third argument + in :c:func:`PyNumber_InPlacePower` which no longer ignored if + :meth:`!__ipow__` is defined. + (Contributed by Serhiy Storchaka in :gh:`86069`.) New modules