Это похоже на ошибку из-за несоответствия между кодом для двоичных и троичных операций (при **=
обрабатывается логикой троичной операции из-за совместного использования кода с 3 аргументами pow
).Двоичные операции на месте проходят через binary_iop1
, в котором есть код для возврата к подпрограмме «не на месте», если обработчик на месте возвращает NotImplemented
:
static PyObject *
binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot)
{
PyNumberMethods *mv = v->ob_type->tp_as_number;
if (mv != NULL) {
binaryfunc slot = NB_BINOP(mv, iop_slot);
if (slot) {
PyObject *x = (slot)(v, w);
if (x != Py_NotImplemented) {
return x;
}
Py_DECREF(x);
}
}
return binary_op1(v, w, op_slot);
}
но из-за различий в коде, необходимых для 3-аргумента pow
, **=
не может пройти этот путь кода, поэтому он имеет свою собственную специальную обработку :
PyObject *
PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
{
if (v->ob_type->tp_as_number &&
v->ob_type->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), "**=");
}
}
Эта специальная обработка фиксирует либо на месте, либо на месте, без отступления, если обработчик на месте не может его обработать.