[Python-Dev] INPLACE_ADD and INPLACE_MULTIPLY oddities in ceval.c

Robert Kern robert.kern at gmail.com
Tue Mar 28 04:45:54 CEST 2006


Guido van Rossum wrote:
> On 3/27/06, Travis Oliphant <oliphant.travis at ieee.org> wrote:
> 
>>If you have Numeric or numpy installed try this:
>>
>>#import Numeric as N
>>import numpy as N
>>
>>a = range(10)
>>b = N.arange(10)
>>
>>a.__iadd__(b)
>>
>>print a
>>
>>Result:
>>
>>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>
>>
>>Contrast the returned output with
>>
>>import numpy as N
>>
>>a = range(10)
>>b = N.arange(10)
>>
>>a += b
>>
>>print a
>>
>>Result:
>>
>>[ 0  2  4  6  8 10 12 14 16 18]
>>
>>Having "a+=b" and "a.__iadd__(b)" do different things seems like an
>>unfortunate bug.
>>
>>It seems to me that the problem is that the INPLACE_ADD and
>>INPLACE_MULTIPLY cases in ceval.c  use PyNumber_InPlace<YYY> instead of
>>trying PySequence_InPlace<YYY> when the object doesn't support the
>>in-place number protocol.
>>
>>I could submit a patch if there is agreement that this is a problem.
> 
> Well how is the interpreter to know whether += meanse numeric add or
> sequence add in any particular case?
> 
> Shouldn't it be numpy's responsibility to implement both operations identically?

"a" is a list object. Travis's question is, "why doesn't the list object
implement both operations identically?" I think the answer is, "it never gets a
chance to."

When a numpy array is on the LHS of an inplace operation, we always want the
numeric add. numpy arrays can't be extended inplace like a list, and a lone "+"
is always a numeric operation for arrays, never a sequence operation. When numpy
arrays are on the LHS of an inplace operation, everything works consistently.

The issue seems to arise from the fact that PyNumber_InPlaceAdd tries to coerce
the LHS and the RHS to a common numerical type first before trying
PySequence_InPlaceConcat. Lists of numbers coerce to numpy arrays just fine, so
this code path is taken, and nothing tests for the sq_inplace_concat or
sq_concat slots.

Personally, I'm willing to just document it in the numpy documentation as a
rarely-seen gotcha. This behavior pretty much affects just us.

-- 
Robert Kern
robert.kern at gmail.com

"I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth."
  -- Umberto Eco



More information about the Python-Dev mailing list