Update PEP and refer to patch.

This commit is contained in:
Georg Brandl 2007-05-02 21:24:11 +00:00
parent 7769a3f2ce
commit 0c4dbfca14
1 changed files with 85 additions and 25 deletions

View File

@ -44,49 +44,109 @@ is replaced by the cleaner and probably more efficient::
For more complex unpacking patterns, the new syntax looks even
cleaner, and the clumsy index handling is not necessary anymore.
Also, if the right-hand value is not a list, but an iterable, it
has to be converted to a list before being able to do slicing; to
avoid creating this temporary list, one has to resort to ::
it = iter(seq)
first = it.next()
rest = list(it)
Specification
=============
A tuple (or list) on the left side of a simple assignment (unpacking
is not defined for augmented assignment) may contain at most one
expression prepended with a single asterisk. For the rest of this
section, the other expressions in the list are called "mandatory".
expression prepended with a single asterisk (which is henceforth
called a "starred" expression, while the other expressions in the
list are called "mandatory"). This designates a subexpression that
will be assigned a list of all items from the iterable being unpacked
that are not assigned to any of the mandatory expressions, or an
empty list if there are no such items.
Note that this also refers to tuples in implicit assignment context,
such as in a ``for`` statement.
For example, if ``seq`` is a slicable sequence, all the following
assignments are equivalent if ``seq`` has at least three elements::
This designates a subexpression that will be assigned a list of all
items from the iterable being unpacked that are not assigned to any
of the mandatory expressions, or an empty list if there are no such
items.
a, b, c = seq[0], seq[1:-1], seq[-1]
a, *b, c = seq
[a, *b, c] = seq
It is an error (as it is currently) if the iterable doesn't contain
enough items to assign to all the mandatory expressions.
It is also an error to use the starred expression as a lone
assignment target, as in ::
*a = range(5)
This, however, is valid syntax::
*a, = range(5)
Note that this proposal also applies to tuples in implicit assignment
context, such as in a ``for`` statement::
for (a, *b) in [(1, 2, 3), (4, 5, 6, 7)]:
print(b)
would print out ::
[2, 3]
[5, 6, 7]
Implementation
==============
The proposed implementation strategy is:
Grammar change
--------------
- add a new grammar rule, ``star_test``, which consists of ``'*'
test`` and is used in test lists
- add a new ASDL type ``Starred`` to represent a starred expression
- catch all cases where starred expressions are not allowed in the AST
and symtable generation stage
- add a new opcode, ``UNPACK_EX``, which will only be used if a
list/tuple to be assigned to contains a starred expression
- change ``unpack_iterable()`` in ceval.c to handle the extended
unpacking case
This feature requires a new grammar rule::
Note that the starred expression element introduced here is universal
and could be used for other purposes in non-assignment context, such
as the ``yield *iterable`` proposal.
star_expr: ['*'] expr
The author has written a draft implementation, but there are some open
issues which will be resolved in case this PEP is looked upon
benevolently.
In these two rules, ``expr`` is changed to ``star_expr``::
comparison: star_expr (comp_op star_expr)*
exprlist: star_expr (',' star_expr)* [',']
Changes to the Compiler
-----------------------
A new ASDL expression type ``Starred`` is added which represents a
starred expression. Note that the starred expression element
introduced here is universal and could later be used for other
purposes in non-assignment context, such as the ``yield *iterable``
proposal.
The compiler is changed to recognize all cases where a starred
expression is invalid and flag them with syntax errors.
A new bytecode instruction, ``UNPACK_EX``, is added, whose argument
has the number of mandatory targets before the starred target in the
lower 8 bits and the number of mandatory targets after the starred
target in the upper 8 bits. For unpacking sequences without starred
expressions, the old ``UNPACK_ITERABLE`` opcode is kept.
Changes to the Bytecode Interpreter
-----------------------------------
The function ``unpack_iterable()`` in ceval.c is changed to handle
the extended unpacking, via an ``argcntafter`` parameter. In the
``UNPACK_EX`` case, the function will do the following:
* collect all items for mandatory targets before the starred one
* collect all remaining items from the iterable in a list
* pop items for mandatory targets after the starred one from the list
* push the single items and the resized list on the stack
Shortcuts for unpacking iterables of known types, such as lists or
tuples, can be added.
The current implementation can be found at the SourceForge Patch
tracker [SFPATCH]_. It now includes a minimal test case.
Open Issues
@ -98,7 +158,7 @@ Open Issues
References
==========
None yet.
.. [SFPATCH] http://python.org/sf/1711529
Copyright