[Python-Dev] PEP 203 Augmented Assignment

Guido van Rossum guido@beopen.com
Thu, 27 Jul 2000 09:22:48 -0500


> > Yes, mostly because there are so many variants based on the kind of
> > loading and storing: for each load-type operator you need 11 GETSET
> > operators, and there are many different load operators: local, global,
> > unspecified (== local by dict instead), by attribute, by index, or by
> > slice...
> 
> Except if you add a new type of bytecode, the 2-argument type. Which is what
> my implementation currently does. It necessitates just 9 new bytecodes that
> way: GETSET_SUBSCR, SLICE+0 through SLICE+3, NAME, FAST, GLOBAL and ATTR.
> The last four need 2 arguments, one for the name-index (or local vrbl
> number) and one for the actual operation.

But the two-arg opcode format slows down the opcode decoding -- and
that's the most time-critical part of all of ceval.c!

> > I am still neutral on the choice between a single AUGOP with an
> > argument that takes an argument specifying the opcode, and 11 new
> > operators: AUGASS_ADD, ...  (Actually, the latter seem the most
> > logical given that we also have BINARY_ADD, ...)
> 
> Agreed. However, there isn't enough place in the current bytecode ranges for
> 9 consecutive non-argument opcodes. I'm also not sure how scarce a commodity
> opcodes are. Then again, it can also be 'undone' later.

There's no need for them to be consecutive!  (The BINARY_* family
isn't even consecutive!)  I say, just some open ranges, like 54-59 and
73-79.

> Yes. How about a ROT_ANY <x> argument opcode while we're at it ? <x> would
> specify the number to rotate... you could even encode *how* to rotate in
> that argument. (using the upper byte, imposing a sensible limit of 255 for
> the number of rotations ;-)

No, let's not overgeneralize.

> > Another alternative that tries to preserve compatibility is to call
> > __getslice__(self, start, end) when the step is None, but
> > __getslice__(self, start, end, step) when it isn't.  Old code will
> > raise a reasonable exception when a step is specified, while
> > step-aware code can specify the step as a default argument value of
> > 1 or None.
> 
> Yes, that's very reasonable. I would suggest making the error 'special',
> in this case, though. So that you don't get a TypeError about incorrect
> number of arguments, but rather a 'object does not support extended slices'
> or some such TypeError.

Yes.

> Actually, it might be worth doing it like this:
> 
> Try to call __getslice__ with unconverted start, stop and step
> If it fails with a TypeError, and step is not None, raise the above error
> Else, convert start and stop to ints like the current normal slice
> behaviour, and try __getslice__ the old way.

No, trying to call something and retrying if it fails is a bad idea:
the code might fail for a very different reason, and retrying it might
mask the bug, or execute a side effect twice...

There's no reason why we can't check whether the step is None; it's
already impossible to find out whether a particular slice was
"lo:hi:None" or "lo:hi:" (once extended slice mode is used).

--Guido van Rossum (home page: http://www.pythonlabs.com/~guido/)