mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Issue #23275: Allow () = iterable assignment syntax
Documentation updates by Martin Panter.
This commit is contained in:
parent
93d22ecc7c
commit
094c9c921c
7 changed files with 41 additions and 41 deletions
|
@ -84,8 +84,8 @@ attributes or items of mutable objects:
|
||||||
assignment_stmt: (`target_list` "=")+ (`expression_list` | `yield_expression`)
|
assignment_stmt: (`target_list` "=")+ (`expression_list` | `yield_expression`)
|
||||||
target_list: `target` ("," `target`)* [","]
|
target_list: `target` ("," `target`)* [","]
|
||||||
target: `identifier`
|
target: `identifier`
|
||||||
: | "(" `target_list` ")"
|
: | "(" [`target_list`] ")"
|
||||||
: | "[" `target_list` "]"
|
: | "[" [`target_list`] "]"
|
||||||
: | `attributeref`
|
: | `attributeref`
|
||||||
: | `subscription`
|
: | `subscription`
|
||||||
: | `slicing`
|
: | `slicing`
|
||||||
|
@ -115,21 +115,25 @@ given with the definition of the object types (see section :ref:`types`).
|
||||||
Assignment of an object to a target list, optionally enclosed in parentheses or
|
Assignment of an object to a target list, optionally enclosed in parentheses or
|
||||||
square brackets, is recursively defined as follows.
|
square brackets, is recursively defined as follows.
|
||||||
|
|
||||||
* If the target list is a single target: The object is assigned to that target.
|
* If the target list is empty: The object must also be an empty iterable.
|
||||||
|
|
||||||
* If the target list is a comma-separated list of targets: The object must be an
|
* If the target list is a single target in parentheses: The object is assigned
|
||||||
iterable with the same number of items as there are targets in the target list,
|
to that target.
|
||||||
and the items are assigned, from left to right, to the corresponding targets.
|
|
||||||
|
* If the target list is a comma-separated list of targets, or a single target
|
||||||
|
in square brackets: The object must be an iterable with the same number of
|
||||||
|
items as there are targets in the target list, and the items are assigned,
|
||||||
|
from left to right, to the corresponding targets.
|
||||||
|
|
||||||
* If the target list contains one target prefixed with an asterisk, called a
|
* If the target list contains one target prefixed with an asterisk, called a
|
||||||
"starred" target: The object must be a sequence with at least as many items
|
"starred" target: The object must be an iterable with at least as many items
|
||||||
as there are targets in the target list, minus one. The first items of the
|
as there are targets in the target list, minus one. The first items of the
|
||||||
sequence are assigned, from left to right, to the targets before the starred
|
iterable are assigned, from left to right, to the targets before the starred
|
||||||
target. The final items of the sequence are assigned to the targets after
|
target. The final items of the iterable are assigned to the targets after
|
||||||
the starred target. A list of the remaining items in the sequence is then
|
the starred target. A list of the remaining items in the iterable is then
|
||||||
assigned to the starred target (the list can be empty).
|
assigned to the starred target (the list can be empty).
|
||||||
|
|
||||||
* Else: The object must be a sequence with the same number of items as there
|
* Else: The object must be an iterable with the same number of items as there
|
||||||
are targets in the target list, and the items are assigned, from left to
|
are targets in the target list, and the items are assigned, from left to
|
||||||
right, to the corresponding targets.
|
right, to the corresponding targets.
|
||||||
|
|
||||||
|
@ -150,11 +154,6 @@ Assignment of an object to a single target is recursively defined as follows.
|
||||||
count for the object previously bound to the name to reach zero, causing the
|
count for the object previously bound to the name to reach zero, causing the
|
||||||
object to be deallocated and its destructor (if it has one) to be called.
|
object to be deallocated and its destructor (if it has one) to be called.
|
||||||
|
|
||||||
* If the target is a target list enclosed in parentheses or in square brackets:
|
|
||||||
The object must be an iterable with the same number of items as there are
|
|
||||||
targets in the target list, and its items are assigned, from left to right,
|
|
||||||
to the corresponding targets.
|
|
||||||
|
|
||||||
.. index:: pair: attribute; assignment
|
.. index:: pair: attribute; assignment
|
||||||
|
|
||||||
* If the target is an attribute reference: The primary expression in the
|
* If the target is an attribute reference: The primary expression in the
|
||||||
|
|
|
@ -282,7 +282,6 @@ class CodeopTests(unittest.TestCase):
|
||||||
ai("if (a == 1 and b = 2): pass")
|
ai("if (a == 1 and b = 2): pass")
|
||||||
|
|
||||||
ai("del 1")
|
ai("del 1")
|
||||||
ai("del ()")
|
|
||||||
ai("del (1,)")
|
ai("del (1,)")
|
||||||
ai("del [1]")
|
ai("del [1]")
|
||||||
ai("del '1'")
|
ai("del '1'")
|
||||||
|
|
|
@ -35,14 +35,6 @@ SyntaxError: invalid syntax
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
SyntaxError: can't assign to keyword
|
SyntaxError: can't assign to keyword
|
||||||
|
|
||||||
It's a syntax error to assign to the empty tuple. Why isn't it an
|
|
||||||
error to assign to the empty list? It will always raise some error at
|
|
||||||
runtime.
|
|
||||||
|
|
||||||
>>> () = 1
|
|
||||||
Traceback (most recent call last):
|
|
||||||
SyntaxError: can't assign to ()
|
|
||||||
|
|
||||||
>>> f() = 1
|
>>> f() = 1
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
SyntaxError: can't assign to function call
|
SyntaxError: can't assign to function call
|
||||||
|
@ -491,10 +483,6 @@ Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
SyntaxError: keyword argument repeated
|
SyntaxError: keyword argument repeated
|
||||||
|
|
||||||
>>> del ()
|
|
||||||
Traceback (most recent call last):
|
|
||||||
SyntaxError: can't delete ()
|
|
||||||
|
|
||||||
>>> {1, 2, 3} = 42
|
>>> {1, 2, 3} = 42
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
SyntaxError: can't assign to literal
|
SyntaxError: can't assign to literal
|
||||||
|
|
|
@ -117,6 +117,27 @@ error)
|
||||||
...
|
...
|
||||||
test.test_unpack.BozoError
|
test.test_unpack.BozoError
|
||||||
|
|
||||||
|
Allow unpacking empty iterables
|
||||||
|
|
||||||
|
>>> () = []
|
||||||
|
>>> [] = ()
|
||||||
|
>>> [] = []
|
||||||
|
>>> () = ()
|
||||||
|
|
||||||
|
Unpacking non-iterables should raise TypeError
|
||||||
|
|
||||||
|
>>> () = 42
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
TypeError: 'int' object is not iterable
|
||||||
|
|
||||||
|
Unpacking to an empty iterable should raise ValueError
|
||||||
|
|
||||||
|
>>> () = [42]
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValueError: too many values to unpack (expected 0)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__test__ = {'doctests' : doctests}
|
__test__ = {'doctests' : doctests}
|
||||||
|
|
|
@ -140,11 +140,6 @@ class FailureTestCase(unittest.TestCase):
|
||||||
'with mock as (None):\n'
|
'with mock as (None):\n'
|
||||||
' pass')
|
' pass')
|
||||||
|
|
||||||
def testAssignmentToEmptyTupleError(self):
|
|
||||||
self.assertRaisesSyntaxError(
|
|
||||||
'with mock as ():\n'
|
|
||||||
' pass')
|
|
||||||
|
|
||||||
def testAssignmentToTupleOnlyContainingNoneError(self):
|
def testAssignmentToTupleOnlyContainingNoneError(self):
|
||||||
self.assertRaisesSyntaxError('with mock as None,:\n pass')
|
self.assertRaisesSyntaxError('with mock as None,:\n pass')
|
||||||
self.assertRaisesSyntaxError(
|
self.assertRaisesSyntaxError(
|
||||||
|
|
|
@ -22,6 +22,9 @@ Release date: 2016-05-16
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #23275: Allow assigning to an empty target list in round brackets:
|
||||||
|
() = iterable.
|
||||||
|
|
||||||
- Issue #26991: Fix possible refleak when creating a function with annotations.
|
- Issue #26991: Fix possible refleak when creating a function with annotations.
|
||||||
|
|
||||||
- Issue #27039: Fixed bytearray.remove() for values greater than 127. Based on
|
- Issue #27039: Fixed bytearray.remove() for values greater than 127. Based on
|
||||||
|
|
|
@ -990,13 +990,8 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
|
||||||
s = e->v.List.elts;
|
s = e->v.List.elts;
|
||||||
break;
|
break;
|
||||||
case Tuple_kind:
|
case Tuple_kind:
|
||||||
if (asdl_seq_LEN(e->v.Tuple.elts)) {
|
|
||||||
e->v.Tuple.ctx = ctx;
|
e->v.Tuple.ctx = ctx;
|
||||||
s = e->v.Tuple.elts;
|
s = e->v.Tuple.elts;
|
||||||
}
|
|
||||||
else {
|
|
||||||
expr_name = "()";
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Lambda_kind:
|
case Lambda_kind:
|
||||||
expr_name = "lambda";
|
expr_name = "lambda";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue