[Python-Dev] Bug in PyNumber_InPlacePower implementation?
Guido van Rossum
guido@python.org
Tue, 28 May 2002 21:00:11 -0400
> I was looking at the implementation of PyNumber_InPlacePower last
> night, and something about it struck me as odd. It starts off:
>
> if (HASINPLACE(v) && 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), "**=");
>
> Now, looking at ternary_op, it appears that under some
> circumstances this could call the nb_inplace_power slot
> of the second or third argument before trying the first
> one:
>
> if (slotv) {
> if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) {
> x = slotw(v, w, z);
>
> i.e. if the 2nd argument is a subtype of the 1st, and it
> has an nb_inplace_power method, it will be called first.
>
> This looks wrong to me. Surely only the *first* argument
> should be checked for an inplace method when doing an
> inplace operation? That's the way it seems to be for
> all the other inplace operations. Is this a bug?
This is exactly the same as what binary_op1() does. I added this
twist intentionally because of a use case where a subclass of a
numeric type wants to override a binary (or ternary) operator defined
by the base class. If the subclass wasn't tried first, it would never
be able to override the case where a base class instance is the left
operand, because the base class implementation is generally happy to
accept a subclass instance as the right operand. (I admit that a
comment explaining this would have been handy. :-)
Do you have a use case where this does the wrong thing, or is this
just a theoretical musing?
--Guido van Rossum (home page: http://www.python.org/~guido/)