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

Armin Rigo arigo at tunes.org
Wed Mar 29 14:51:48 CEST 2006


Hi all,

On Tue, Mar 28, 2006 at 09:50:49AM -0800, Guido van Rossum wrote:
> C extensions are my main worry -- OTOH if += for a list can already
> passes arbitrary types as the argument, then any extension types
> should be ready to expect this, right?

Yes, I don't think C extensions are going to segfault.  My worry is
about returning a different result than before.  Actually I believe the
problem is not specific to C extensions.  Here are some typical behavior
changes that could be observed in pure Python already:

class X(object):
    def __radd__(self, other):
        return 42
    def __iter__(self):
        return iter("xyz")
    def __rmul__(self, other):
        return 42
    def __index__(self):
        return 5

t = []
t += X()
print t            # current: 42   new: ['x', 'y', 'z']
print [1] * X()    # current: 42   new: [1, 1, 1, 1, 1]

Another visible difference is that the __add__/__iadd__/__mul__/__imul__
methods of lists, tuples, strings etc., will return NotImplemented
instead of raising the TypeError themselves.  This could impact user
subclasses of these built-in types trying to override and call the super
methods, not expecting a NotImplemented result (a reason why
NotImplemented should have been an exception in the first place IMHO).

(A different bug I found is that [1].__mul__(X()) with an __index__able
class X currently raises TypeError, even though [1]*X() works just
fine.)

This seems to be it on the incompatibility side.  I'd vote for the
change anyway because the language specs -- as well as PyPy and probably
all Python implementations other than CPython -- don't have this
double-slot inconsistency and already show the "new" behavior.  For what
it's worth no CPython test breaks on top of PyPy because of this.

If this change is accepted I'll submit a patch for 2.5.


A bientot,

Armin


More information about the Python-Dev mailing list