[Python-Dev] PEP 203 Augmented Assignment

Thomas Wouters thomas@xs4all.net
Thu, 27 Jul 2000 15:00:36 +0200


On Thu, Jul 27, 2000 at 08:37:24AM -0500, Guido van Rossum wrote:
> > I take it you rather see a 'AUGOP' bytecode than a 'GETSET_<type>' bytecode,
> > that does the loading, operation and storing ? Not that I disagree, not at
> > all, I just want to have that clear ;)

> 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.

> 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.

> > What's so special about slice assignment ?

> The only special thing about slice assignment is that there are 12
> extra opcodes to deal with slices in the non-augmented-assignment
> case.  I was making a case for avoiding this explosion, but somehow I
> got lost in my own train of thought. :(

There's no explosion in the augmented assignment case, anyhow: either it's
just 4 opcodes for handling slices, or it reuses the current opcodes. 

> So we need a new opcode ROT4 (or ROT_FOUR to be consistent in the
> spelling).

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 ;-)

> > class X:
> >     def __get_newslice__(self, (start, end, step)):

> > where the type of start, end and step is not defined. This can be done with
> > slice objects and sequence-unpacking, of course, but it makes it a lot more
> > usable.

> 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.

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.

Or is that too much magic ? I don't think it'll break anything written in
Python code, but I'm not sure what to do with the C API... But it's easier
to break the API than Python code, me thinks.

Break-over-godda-run-ly y'rs,
-- 
Thomas Wouters <thomas@xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!