@@ -9992,13 +9992,46 @@ slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus)
9992
9992
{
9993
9993
if (modulus == Py_None )
9994
9994
return slot_nb_power_binary (self , other );
9995
- /* Three-arg power doesn't use __rpow__. But ternary_op
9996
- can call this when the second argument's type uses
9997
- slot_nb_power, so check before calling self.__pow__. */
9995
+
9996
+ /* The following code is a copy of SLOT1BINFULL, but for three arguments. */
9997
+ PyObject * stack [3 ];
9998
+ PyThreadState * tstate = _PyThreadState_GET ();
9999
+ int do_other = !Py_IS_TYPE (self , Py_TYPE (other )) &&
10000
+ Py_TYPE (other )-> tp_as_number != NULL &&
10001
+ Py_TYPE (other )-> tp_as_number -> nb_power == slot_nb_power ;
9998
10002
if (Py_TYPE (self )-> tp_as_number != NULL &&
9999
10003
Py_TYPE (self )-> tp_as_number -> nb_power == slot_nb_power ) {
10000
- PyObject * stack [3 ] = {self , other , modulus };
10001
- return vectorcall_method (& _Py_ID (__pow__ ), stack , 3 );
10004
+ PyObject * r ;
10005
+ if (do_other && PyType_IsSubtype (Py_TYPE (other ), Py_TYPE (self ))) {
10006
+ int ok = method_is_overloaded (self , other , & _Py_ID (__rpow__ ));
10007
+ if (ok < 0 ) {
10008
+ return NULL ;
10009
+ }
10010
+ if (ok ) {
10011
+ stack [0 ] = other ;
10012
+ stack [1 ] = self ;
10013
+ stack [2 ] = modulus ;
10014
+ r = vectorcall_maybe (tstate , & _Py_ID (__rpow__ ), stack , 3 );
10015
+ if (r != Py_NotImplemented )
10016
+ return r ;
10017
+ Py_DECREF (r );
10018
+ do_other = 0 ;
10019
+ }
10020
+ }
10021
+ stack [0 ] = self ;
10022
+ stack [1 ] = other ;
10023
+ stack [2 ] = modulus ;
10024
+ r = vectorcall_maybe (tstate , & _Py_ID (__pow__ ), stack , 3 );
10025
+ if (r != Py_NotImplemented ||
10026
+ Py_IS_TYPE (other , Py_TYPE (self )))
10027
+ return r ;
10028
+ Py_DECREF (r );
10029
+ }
10030
+ if (do_other ) {
10031
+ stack [0 ] = other ;
10032
+ stack [1 ] = self ;
10033
+ stack [2 ] = modulus ;
10034
+ return vectorcall_maybe (tstate , & _Py_ID (__rpow__ ), stack , 3 );
10002
10035
}
10003
10036
Py_RETURN_NOTIMPLEMENTED ;
10004
10037
}
0 commit comments