According to Issue23275, these are basically quirks causing no real harm but also no utility. Note that [] = ()
does not alter the list
literal:
>>> [] = ()
>>> type([])
<class 'list'>
[] = x
statements basically assert that x
is iterable and that x
is empty (although no-one would recommend using them this way), e.g.
>>> [] = (1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> [] = (1,)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
As John Y comments it is best to think of [] = ()
as not an assignment but a way of being consistent with Python's iterable unpacking syntax.
As ArrowCase comments, this syntax also extends to multiple assignments:
>>> a = [] = ()
>>> a
()
Looking at the CPython bytecode of the multiple assignment illustrates that this operations are similar to the normal iterable unpacking syntax, using the UNPACK_SEQUENCE
instruction:
>>> dis.dis('a = [] = ()')
1 0 BUILD_TUPLE 0
2 DUP_TOP
4 STORE_NAME 0 (a)
6 UNPACK_SEQUENCE 0
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
>>> dis.dis('[a, b] = (1, 2)')
1 0 LOAD_CONST 3 ((1, 2))
2 UNPACK_SEQUENCE 2
4 STORE_NAME 0 (a)
6 STORE_NAME 1 (b)
8 LOAD_CONST 2 (None)
10 RETURN_VALUE
The same Issue23275 states that () = ()
was added as valid syntax to Python 3 for concordance. It was decided that removing [] = ()
would break code needlessly, since it causes no harm and fits with iterable unpacking logic. {} = ()
is still invalid because the unpacking syntax does not make sense in this context with braces.
In case anyone is wondering, syntax like list() = ()
is simply syntactically invalid, because you can never assign to function call.