-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
gh-130104: Call __rpow__ in ternary pow() if necessary #130251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
85192cb
b563d1c
56daac8
55fbb13
230a832
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -458,6 +458,11 @@ 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`.) | ||||||||||||||||||||||
|
||||||||||||||||||||||
* Three-argument :func:`pow` now try calling :meth:`~object.__rpow__` if necessary. | ||||||||||||||||||||||
Previously it was only called in two-argument :func:`!pow` and the binary | ||||||||||||||||||||||
power operator. | ||||||||||||||||||||||
(Contributed by Serhiy Storchaka in :gh:`130104`.) | ||||||||||||||||||||||
|
||||||||||||||||||||||
Comment on lines
+461
to
+465
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the difference? |
||||||||||||||||||||||
* Add a built-in implementation for HMAC (:rfc:`2104`) using formally verified | ||||||||||||||||||||||
code from the `HACL* <https://github.com/hacl-star/hacl-star/>`__ project. | ||||||||||||||||||||||
This implementation is used as a fallback when the OpenSSL implementation | ||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Three-argument :func:`pow` now try calling :meth:`~object.__rpow__` if | ||
necessary. | ||
Previously it was only called in two-argument :func:`!pow` and the binary | ||
power operator. |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -9992,13 +9992,46 @@ slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus) | |||||||||||||
{ | ||||||||||||||
if (modulus == Py_None) | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's insert some PEP-7 here |
||||||||||||||
return slot_nb_power_binary(self, other); | ||||||||||||||
/* Three-arg power doesn't use __rpow__. But ternary_op | ||||||||||||||
can call this when the second argument's type uses | ||||||||||||||
slot_nb_power, so check before calling self.__pow__. */ | ||||||||||||||
|
||||||||||||||
/* The following code is a copy of SLOT1BINFULL, but for three arguments. */ | ||||||||||||||
PyObject* stack[3]; | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
PyThreadState *tstate = _PyThreadState_GET(); | ||||||||||||||
int do_other = !Py_IS_TYPE(self, Py_TYPE(other)) && | ||||||||||||||
Py_TYPE(other)->tp_as_number != NULL && | ||||||||||||||
Py_TYPE(other)->tp_as_number->nb_power == slot_nb_power; | ||||||||||||||
Comment on lines
+9999
to
+10001
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use a lot of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code is a copy of SLOT1BINFULL. I do not want to introduce more difference than necessary. We can make SLOT1BINFULL supporting the third argument, but I am not sure that it is worth.
Comment on lines
+9999
to
+10001
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
if (Py_TYPE(self)->tp_as_number != NULL && | ||||||||||||||
Py_TYPE(self)->tp_as_number->nb_power == slot_nb_power) { | ||||||||||||||
PyObject* stack[3] = {self, other, modulus}; | ||||||||||||||
return vectorcall_method(&_Py_ID(__pow__), stack, 3); | ||||||||||||||
PyObject *r; | ||||||||||||||
if (do_other && PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) { | ||||||||||||||
int ok = method_is_overloaded(self, other, &_Py_ID(__rpow__)); | ||||||||||||||
if (ok < 0) { | ||||||||||||||
return NULL; | ||||||||||||||
} | ||||||||||||||
if (ok) { | ||||||||||||||
stack[0] = other; | ||||||||||||||
stack[1] = self; | ||||||||||||||
stack[2] = modulus; | ||||||||||||||
r = vectorcall_maybe(tstate, &_Py_ID(__rpow__), stack, 3); | ||||||||||||||
if (r != Py_NotImplemented) | ||||||||||||||
return r; | ||||||||||||||
Comment on lines
+10015
to
+10016
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
Py_DECREF(r); | ||||||||||||||
do_other = 0; | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
stack[0] = self; | ||||||||||||||
stack[1] = other; | ||||||||||||||
stack[2] = modulus; | ||||||||||||||
r = vectorcall_maybe(tstate, &_Py_ID(__pow__), stack, 3); | ||||||||||||||
if (r != Py_NotImplemented || | ||||||||||||||
Py_IS_TYPE(other, Py_TYPE(self))) | ||||||||||||||
return r; | ||||||||||||||
Comment on lines
+10025
to
+10027
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
Py_DECREF(r); | ||||||||||||||
} | ||||||||||||||
if (do_other) { | ||||||||||||||
stack[0] = other; | ||||||||||||||
stack[1] = self; | ||||||||||||||
stack[2] = modulus; | ||||||||||||||
return vectorcall_maybe(tstate, &_Py_ID(__rpow__), stack, 3); | ||||||||||||||
} | ||||||||||||||
Py_RETURN_NOTIMPLEMENTED; | ||||||||||||||
} | ||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you should use
object.__rpow__(self, other, modulo=None)
signature?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not understand you. Were and how can it be used?
This sentence is a copy of the corresponding sentence for
__pow__
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I meant L3329-3342 above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. There are other similar cases (for example
__round__
), so I will left this for other issue. Actually,__pow__()
and__round__()
are never called with None, so it is not necessary that they support None.