-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
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 1 commit
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 |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Ternary :func:`pow` now try calling :meth:`~object.__rpow__` if | ||
| necessary. | ||
| Previously it was only called in binary :func:`!pow` and the binary | ||
| power operator. |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9628,7 +9628,7 @@ FUNCNAME(PyObject *self, PyObject *other) \ | |||||||||||||
| { \ | ||||||||||||||
| PyObject* stack[2]; \ | ||||||||||||||
| PyThreadState *tstate = _PyThreadState_GET(); \ | ||||||||||||||
| int do_other = !Py_IS_TYPE(self, Py_TYPE(other)) && \ | ||||||||||||||
| int do_other = /*(void*)TESTFUNC != (void*)slot_nb_power &&*/ !Py_IS_TYPE(self, Py_TYPE(other)) && \ | ||||||||||||||
skirpichev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||
| Py_TYPE(other)->tp_as_number != NULL && \ | ||||||||||||||
| Py_TYPE(other)->tp_as_number->SLOTNAME == TESTFUNC; \ | ||||||||||||||
| if (Py_TYPE(self)->tp_as_number != NULL && \ | ||||||||||||||
|
|
@@ -9813,13 +9813,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.