[Python-ideas] Yet More Unpacking Generalizations (or, Dictionary Literals as lvalues)

Chris Angelico rosuav at gmail.com
Wed Aug 12 18:10:13 CEST 2015


On Wed, Aug 12, 2015 at 11:57 PM, Scott Sanderson
<scott.b.sanderson90 at gmail.com> wrote:
> LOAD_NAME 'values'  # Push rvalue onto the stack.
> LOAD_CONST 'dict'   # Push top-level keys onto the stack.
> LOAD_CONST 'tuple'
> LOAD_CONST 'name'
> UNPACK_MAP 3        # Unpack keys. Pops values and all keys from the stack.
>                     # TOS  = values['name']
>                     # TOS1 = values['tuple']
>                     # TOS2 = values['dict']
>
> STORE_FAST name     # Terminal names are simply stored.
>
> UNPACK_SEQUENCE 2   # Push the two entries in values['tuple'] onto the
> stack.
>                     # TOS  = values['tuple'][0]
>                     # TOS1 = values['tuple'][1]
>                     # TOS2 = values['dict']
> STORE_FAST x
> STORE_FAST y

This sounds reasonable in theory; is it going to have problems with
the non-orderedness of dictionaries? With sequence unpacking, it's
straight-forward - you evaluate things in a known order, you iterate
over the thing, you assign. In this case, you might end up with some
bizarre stack manipulation needed to make this work. Inside that
UNPACK_MAP opcode, arbitrary code could be executed (imagine if the
RHS is not a dict per se, but an object with a __getitem__ method), so
it'll need to be popping some things off and pushing others on, and
presumably would need to know what goes where.

Unless, of course, this doesn't "pop" and "push", but does some sort
of replacement. Suppose you load the keys first, and only once those
are loaded, you load the rvalue - so the rvalue is on the top of the
stack. "UNPACK_MAP 3" means this:

1) Pop the top item off the stack - it is the map we're working with.
2) Reach 3 items down in the stack. Take that item, subscript our map
with it, and replace that stack entry with the result.
3) Reach 2 items down, subscript, replace. Repeat till we subscript
with the top of the stack.

I've no idea how plausible that is, but it'd kinda work. It would also
mean you could evaluate the keys in the order that they're shown in
the dict display *and* assign to them in that order, which the current
proposal doesn't do (it assigns in order, but evaluates in reverse
order).

Stupid, unworkable idea?

ChrisA


More information about the Python-ideas mailing list