[Python-Dev] INPLACE_ADD and INPLACE_MULTIPLY oddities in ceval.c
tim.hochberg at ieee.org
Wed Mar 29 17:45:10 CEST 2006
Armin Rigo wrote:
> Hi Greg,
> On Wed, Mar 29, 2006 at 12:38:55PM +1200, Greg Ewing wrote:
>>I'm really thinking more about the non-inplace operators.
>>If nb_add and sq_concat are collapsed into a single slot,
>>it seems to me that if you do
>> a = [1, 2, 3]
>> b = array([4, 5, 6])
>> c = a + b
>>then a will be asked "Please add yourself to b", and a
>>will say "Okay, I know how to do that!" and promptly
>>concatenate itself with b.
> No: there is a difference between + and += for lists. You can only
> concatenate exactly a list to a list. Indeed:
> >>> .__add__((2, 3))
> TypeError: can only concatenate list (not "tuple") to list
> By contrast, list += is like extend() and accepts any iterable.
> So if we provide a complete fix, .__add__(x) will be modified to
> return NotImplemented instead of raising TypeError if x is not a list,
> and then [1,2,3]+array([4,5,6]) will fall back to array.__radd__() as
Ouch. Assuming the same path is followed with tuples, I think that this
means the following behaviour will continue:
>>> t = (1,2,3)
>>> a = array([4,5,6])
>>> t += a
array([5, 7, 9])
That's not particularly desirable. There's not much to be done about it
short of adding __iadd__s everywhere, which is probably brittle and
unfriendly. And, admittedly this is a corner case that's very rarely
going to cause trouble. Still, perhaps for Py3K it's worth considering
if PyNumber_InplaceAdd should only call __iadd__ and __add__, not
__radd__. Thus giving the target object complete control during inplace
adds. Similarly for other inplace operations, of course.
I'm not certain that all of the consequences of this change would be
benign, but it's something to consider.
> I'll try harder to see if there is a reasonable example whose behavior
> would change...
More information about the Python-Dev