PEP 448: Updates from Neil Girdhar.
This commit is contained in:
parent
dd8631553c
commit
0ee06e9bd1
113
pep-0448.txt
113
pep-0448.txt
|
@ -16,30 +16,22 @@ Abstract
|
|||
========
|
||||
|
||||
This PEP proposes extended usages of the ``*`` iterable unpacking
|
||||
operator to allow unpacking in more positions, an arbitrary number of
|
||||
times, and in several additional circumstances.
|
||||
operator and ``**`` dictionary unpacking operator
|
||||
to allow unpacking in more positions, an arbitrary number of
|
||||
times, and in additional circumstances. Specifically
|
||||
in function calls, in comprehensions and generator expressions,
|
||||
and in displays.
|
||||
|
||||
Specifically:
|
||||
|
||||
Arbitrarily positioned unpacking operators::
|
||||
Function calls are proposed to support an arbitrary number of
|
||||
unpackings rather than just one::
|
||||
|
||||
>>> print(*[1], *[2], 3)
|
||||
1 2 3
|
||||
>>> dict(**{'x': 1}, y=2, **{'z': 3})
|
||||
{'x': 1, 'y': 2, 'z': 3}
|
||||
|
||||
Function calls currently have the restriction that keyword arguments
|
||||
must follow positional arguments and ``**`` unpackings must additionally
|
||||
follow ``*`` unpackings. Because of the new levity for ``*`` and ``**``
|
||||
unpackings, it may be advisable to lift some or all of these
|
||||
restrictions.
|
||||
|
||||
As currently, if an argument is given multiple times - such as a
|
||||
positional argument given both positionally and by keyword - a
|
||||
TypeError is raised.
|
||||
|
||||
Unpacking is proposed to be allowed inside tuples, lists, sets,
|
||||
dictionaries and comprehensions::
|
||||
Unpacking is proposed to be allowed inside tuple, list, set,
|
||||
and dictionary displays::
|
||||
|
||||
>>> *range(4), 4
|
||||
(0, 1, 2, 3, 4)
|
||||
|
@ -50,10 +42,25 @@ dictionaries and comprehensions::
|
|||
>>> {'x': 1, **{'y': 2}}
|
||||
{'x': 1, 'y': 2}
|
||||
|
||||
In sets and dictionaries, this provides a concise overriding
|
||||
notation::
|
||||
|
||||
>>> {'x': 1, **{'x': 2}}
|
||||
{'x': 2}
|
||||
|
||||
>>> {**{'x': 2}, 'x': 1}
|
||||
{'x': 1}
|
||||
|
||||
Unpacking is proposed to be allowed inside list, set,
|
||||
and dictionary comprehensions::
|
||||
|
||||
>>> ranges = [range(i) for i in range(5)]
|
||||
>>> [*item for item in ranges]
|
||||
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]
|
||||
|
||||
>>> {*item for item in ranges}
|
||||
{0, 1, 2, 3}
|
||||
|
||||
|
||||
Rationale
|
||||
=========
|
||||
|
@ -124,38 +131,29 @@ Other uses are possible, but expected to occur rarely.
|
|||
Specification
|
||||
=============
|
||||
|
||||
Function calls may accept an unbound number of ``*`` and ``**``
|
||||
Function calls may accept an unbounded number of ``*`` and ``**``
|
||||
unpackings. There will be no restriction of the order of positional
|
||||
arguments with relation to ``*`` unpackings nor any restriction of the
|
||||
order of keyword arguments with relation to ``**`` unpackings.
|
||||
|
||||
Function calls currently have the restriction that keyword arguments
|
||||
must follow positional arguments and ``**`` unpackings must additionally
|
||||
follow ``*`` unpackings. Because of the new levity for ``*`` and ``**``
|
||||
unpackings, it may be advisable to list some or all of these
|
||||
restrictions.
|
||||
follow ``*`` unpackings.
|
||||
|
||||
As currently, if an argument is given multiple times - such as a
|
||||
positional argument given both positionally and by keyword - a
|
||||
TypeError is raised.
|
||||
Currently, if an argument is given multiple times — such as a
|
||||
positional argument given both positionally and by keyword — a
|
||||
``TypeError`` is raised. This remains true for duplicate arguments
|
||||
provided through multiple keyword argument unpackings,
|
||||
e.g. ``f(**{'x': 2}, **{'x': 3})``.
|
||||
|
||||
If the restrictions are kept, a function call will look like this::
|
||||
A function looks like this::
|
||||
|
||||
function(
|
||||
argument or *args, argument or *args, ...,
|
||||
kwargument or *args, kwargument or *args, ...,
|
||||
kwargument or **kwargs, kwargument or **kwargs, ...
|
||||
)
|
||||
|
||||
If they are removed completely, a function call will look like this::
|
||||
|
||||
function(
|
||||
argument or keyword_argument or *args or **kwargs,
|
||||
argument or keyword_argument or *args or **kwargs,
|
||||
...
|
||||
argument or *args, argument or *args, ...,
|
||||
kwargument or *args, kwargument or *args, ...,
|
||||
kwargument or **kwargs, kwargument or **kwargs, ...
|
||||
)
|
||||
|
||||
|
||||
Tuples, lists, sets and dictionaries will allow unpacking. This will
|
||||
act as if the elements from unpacked items were inserted in order at
|
||||
the site of unpacking, much as happens in unpacking in a function-call.
|
||||
|
@ -168,7 +166,7 @@ Comprehensions, by simple extension, will support unpacking. As before,
|
|||
dictionaries require ``**`` unpacking, all the others require ``*``
|
||||
unpacking and key priorities are unchanged.
|
||||
|
||||
Examples include::
|
||||
For example::
|
||||
|
||||
{*[1, 2, 3], 4, 5, *{6, 7, 8}}
|
||||
|
||||
|
@ -178,45 +176,30 @@ Examples include::
|
|||
|
||||
{**locals(), "override": None}
|
||||
|
||||
However, ``f(*x for x in it)`` and ``f(**x for x in it)`` continue
|
||||
to raise SyntaxError.
|
||||
|
||||
|
||||
Disadvantages
|
||||
=============
|
||||
|
||||
If the current restrictions for function call arguments (keyword
|
||||
arguments must follow positional arguments and ``**`` unpackings must
|
||||
additionally follow ``*`` unpackings) are kept, the allowable orders
|
||||
for arguments in a function call is more complicated than before.
|
||||
The allowable orders for arguments in a function call is more
|
||||
complicated than before.
|
||||
The simplest explanation for the rules may be "positional arguments
|
||||
come first and keyword arguments follow, but ``*`` unpackings are
|
||||
allowed after keyword arguments".
|
||||
come first and keyword arguments follow, but iterable unpackings are
|
||||
allowed after keyword arguments" or "iterable arguments precede
|
||||
all keyword arguments and keyword argument unpackings, and iterable
|
||||
argument unpackings precede all keyword argument unpackings".
|
||||
|
||||
If the current restrictions are lifted, there are no obvious gains to
|
||||
code as the only new orders that are allowed look silly: ``f(a, e=e,
|
||||
d=d, b, c)`` being a simpler example.
|
||||
|
||||
|
||||
Whilst ``*elements, = iterable`` causes ``elements`` to be a list,
|
||||
While ``*elements, = iterable`` causes ``elements`` to be a list,
|
||||
``elements = *iterable,`` causes ``elements`` to be a tuple. The
|
||||
reason for this may not be obvious at first glance and may confuse
|
||||
people unfamiliar with the construct.
|
||||
reason for this may confuse people unfamiliar with the construct.
|
||||
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
An implementation for an old version of Python 3 is found at Issue
|
||||
2292 on bug tracker [1]_, although several changes should be made:
|
||||
|
||||
- It has yet to be updated to the most recent Python version
|
||||
|
||||
- It features a now redundant replacement for "yield from" which
|
||||
should be removed
|
||||
|
||||
- It also loses support for calling function with keyword arguments before
|
||||
positional arguments, which is an unnecessary backwards-incompatible change
|
||||
|
||||
- If the restrictions on the order of arguments in a function call are
|
||||
partially or fully lifted, they would need to be included
|
||||
An implementation for Python 3.5 is found at Issue 2292 on bug tracker [1]_.
|
||||
|
||||
|
||||
References
|
||||
|
|
Loading…
Reference in New Issue