mirror of
https://github.com/python/cpython.git
synced 2025-12-10 02:50:09 +00:00
bpo-38302: __pow__/__rpow__ now called when __ipow__ returns NotImplemented (#16459)
This commit is contained in:
parent
5e48e83688
commit
cc02b4f2e8
4 changed files with 73 additions and 21 deletions
|
|
@ -882,10 +882,8 @@ static PyObject *
|
|||
ternary_op(PyObject *v,
|
||||
PyObject *w,
|
||||
PyObject *z,
|
||||
const int op_slot
|
||||
#ifndef NDEBUG
|
||||
, const char *op_name
|
||||
#endif
|
||||
const int op_slot,
|
||||
const char *op_name
|
||||
)
|
||||
{
|
||||
PyNumberMethods *mv = Py_TYPE(v)->tp_as_number;
|
||||
|
|
@ -955,16 +953,18 @@ ternary_op(PyObject *v,
|
|||
if (z == Py_None) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
"unsupported operand type(s) for ** or pow(): "
|
||||
"unsupported operand type(s) for %.100s: "
|
||||
"'%.100s' and '%.100s'",
|
||||
op_name,
|
||||
Py_TYPE(v)->tp_name,
|
||||
Py_TYPE(w)->tp_name);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
"unsupported operand type(s) for pow(): "
|
||||
"unsupported operand type(s) for %.100s: "
|
||||
"'%.100s', '%.100s', '%.100s'",
|
||||
op_name,
|
||||
Py_TYPE(v)->tp_name,
|
||||
Py_TYPE(w)->tp_name,
|
||||
Py_TYPE(z)->tp_name);
|
||||
|
|
@ -972,13 +972,6 @@ ternary_op(PyObject *v,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define TERNARY_OP(v, w, z, op_slot, op_name) ternary_op(v, w, z, op_slot)
|
||||
#else
|
||||
# define TERNARY_OP(v, w, z, op_slot, op_name) ternary_op(v, w, z, op_slot, op_name)
|
||||
#endif
|
||||
|
||||
|
||||
#define BINARY_FUNC(func, op, op_name) \
|
||||
PyObject * \
|
||||
func(PyObject *v, PyObject *w) { \
|
||||
|
|
@ -1077,7 +1070,7 @@ PyNumber_Remainder(PyObject *v, PyObject *w)
|
|||
PyObject *
|
||||
PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
|
||||
{
|
||||
return TERNARY_OP(v, w, z, NB_SLOT(nb_power), "** or pow()");
|
||||
return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
|
||||
}
|
||||
|
||||
/* Binary in-place operators */
|
||||
|
|
@ -1140,6 +1133,24 @@ binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot,
|
|||
return result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
ternary_iop(PyObject *v, PyObject *w, PyObject *z, const int iop_slot, const int op_slot,
|
||||
const char *op_name)
|
||||
{
|
||||
PyNumberMethods *mv = Py_TYPE(v)->tp_as_number;
|
||||
if (mv != NULL) {
|
||||
ternaryfunc slot = NB_TERNOP(mv, iop_slot);
|
||||
if (slot) {
|
||||
PyObject *x = (slot)(v, w, z);
|
||||
if (x != Py_NotImplemented) {
|
||||
return x;
|
||||
}
|
||||
Py_DECREF(x);
|
||||
}
|
||||
}
|
||||
return ternary_op(v, w, z, op_slot, op_name);
|
||||
}
|
||||
|
||||
#define INPLACE_BINOP(func, iop, op, op_name) \
|
||||
PyObject * \
|
||||
func(PyObject *v, PyObject *w) { \
|
||||
|
|
@ -1237,13 +1248,8 @@ PyNumber_InPlaceRemainder(PyObject *v, PyObject *w)
|
|||
PyObject *
|
||||
PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
|
||||
{
|
||||
if (Py_TYPE(v)->tp_as_number &&
|
||||
Py_TYPE(v)->tp_as_number->nb_inplace_power != NULL) {
|
||||
return TERNARY_OP(v, w, z, NB_SLOT(nb_inplace_power), "**=");
|
||||
}
|
||||
else {
|
||||
return TERNARY_OP(v, w, z, NB_SLOT(nb_power), "**=");
|
||||
}
|
||||
return ternary_iop(v, w, z, NB_SLOT(nb_inplace_power),
|
||||
NB_SLOT(nb_power), "**=");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue