msg234324 - (view) |
Author: Devin Jeanpierre (Devin Jeanpierre) * |
Date: 2015-01-19 19:05 |
>>> [] = ()
>>> () = []
File "<stdin>", line 1
SyntaxError: can't assign to ()
This contradicts the assignment grammar, which would make both illegal: https://docs.python.org/3/reference/simple_stmts.html#assignment-statements
|
msg234325 - (view) |
Author: R. David Murray (r.david.murray) *  |
Date: 2015-01-19 19:22 |
My guess is that it is not worth complicating the parser in order to make these two cases consistent, and it should be treated as a doc error. We'll see what other developers think.
|
msg234326 - (view) |
Author: Raymond Hettinger (rhettinger) *  |
Date: 2015-01-19 20:12 |
The starting point is recognizing that this has been around for very long time and is harmless.
|
msg234361 - (view) |
Author: Kyle Buzsaki (Kyle.Buzsaki) |
Date: 2015-01-20 09:25 |
It seems that assigning to [] is the odd one out in this case. Why is this even possible?
>>> [] = ()
>>> [] = {}
>>> [] = set()
>>> list() = ()
File "<stdin>", line 1
SyntaxError: can't assign to function call
>>> () = []
File "<stdin>", line 1
SyntaxError: can't assign to ()
>>> {} = []
File "<stdin>", line 1
SyntaxError: can't assign to literal
>>> set() = []
File "<stdin>", line 1
SyntaxError: can't assign to function call
>>>
|
msg234364 - (view) |
Author: Martin Panter (martin.panter) *  |
Date: 2015-01-20 09:40 |
But () is the odd one out if you consider
>>> [a, b] = range(2)
>>> [] = range(0)
>>> (a, b) = range(2)
>>> () = range(0)
File "<stdin>", line 1
SyntaxError: can't assign to ()
|
msg234365 - (view) |
Author: Eryk Sun (eryksun) *  |
Date: 2015-01-20 10:19 |
In ast.c, set_context checks for assignment to an empty tuple, but not an empty list.
case List_kind:
e->v.List.ctx = ctx;
s = e->v.List.elts;
break;
case Tuple_kind:
if (asdl_seq_LEN(e->v.Tuple.elts)) {
e->v.Tuple.ctx = ctx;
s = e->v.Tuple.elts;
}
else {
expr_name = "()";
}
break;
https://hg.python.org/cpython/file/ab2c023a9432/Python/ast.c#l912
|
msg241473 - (view) |
Author: Alyssa Coghlan (ncoghlan) *  |
Date: 2015-04-19 02:47 |
As Raymond notes, this is a fairly harmless quirk - it changes a SyntaxError to an iterable length dependent ValueError:
>>> () = []
File "<stdin>", line 1
SyntaxError: can't assign to ()
>>> [] = ()
>>> [] = [1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 0)
I only found out about this after being puzzled when a typo in a live demo at PyCon 2015 failed to fail as I expected after seeing the presenter type a "[]" into the LHS of an assignment instead of the intended "_".
Removing the data dependence to make the assignment fail immediately (even if never tested against a non-empty iterable) would involve making the handling of List_kind match that of Tuple_kind in the switch statement that eryksun quoted.
I don't think it's an urgent fix, but if someone wanted to fix it (including a new test), I think it would be a reasonable contribution to accept.
|
msg241474 - (view) |
Author: Martin Panter (martin.panter) *  |
Date: 2015-04-19 03:34 |
I would prefer this be fixed in the opposite direction, to allow “unpacking” an empty iterable using round brackets. I have used this syntax on purpose as a concise way to ensure that a generator is exhaused with no more yields:
>>> def gen():
... yield "partial computation"
... print("computation allowed to complete")
...
>>> g = gen()
>>> next(g)
'partial computation'
>>> [] = g
computation allowed to complete
|
msg241523 - (view) |
Author: R. David Murray (r.david.murray) *  |
Date: 2015-04-19 17:57 |
There is also no reason to break currently working code, which turning this into a syntax error would od.
|
msg241673 - (view) |
Author: Mark Dickinson (mark.dickinson) *  |
Date: 2015-04-20 18:28 |
> There is also no reason to break currently working code
Agreed. To take one example, David Beazley's PyCon 2015 talk would have been broken by the suggested change! (See https://www.youtube.com/watch?v=MCs5OvhV9S4, at around the 42:17 mark.)
If there's any code change resulting from this issue, I also think it should be to make assignment to `()` legal.
|
msg241790 - (view) |
Author: Berker Peksag (berker.peksag) *  |
Date: 2015-04-22 09:05 |
I don't have a strong opinion on this, but here is a patch to make () = [] a valid assignment.
|
msg241792 - (view) |
Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) *  |
Date: 2015-04-22 09:42 |
About the patch: I'm sure there are other tests to change,
in test_syntax.py for example::
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):
File "<doctest test.test_syntax[3]>", line 1
SyntaxError: can't assign to ()
|
msg244157 - (view) |
Author: Rahul Gupta (Rahul Gupta) |
Date: 2015-05-27 12:28 |
isn't it logical?
[] is a mutable data structure
while () is a immutable data structure
(b, a) = [1, 2] is fine because a and b are mutable
|
msg244159 - (view) |
Author: Devin Jeanpierre (Devin Jeanpierre) * |
Date: 2015-05-27 12:42 |
[a, b] = (1, 2) is also fine.
|
msg244161 - (view) |
Author: Martin Panter (martin.panter) *  |
Date: 2015-05-27 12:53 |
I prefer to unpack into square brackets in general because it is a mnemonic for the star argument being a list:
>>> (a, *b) = range(3)
>>> a
0
>>> b # A list, even though it was unpacked using tuple-like syntax
[1, 2]
|
msg244208 - (view) |
Author: Raymond Hettinger (rhettinger) *  |
Date: 2015-05-27 17:47 |
Berker's patch looks good.
It has several virtues:
* the error message is reasonable and clear
* it makes the language more consistent
* it doesn't break any existing code.
* it makes the AST a little simpler and faster
by removing a special case
The patch needs to updated:
* remove the whatsnew entry
* fix test_codeop which expects "del ()" to raise SyntaxError
* fix test_syntax which fails on "() = 1" and "del ()"
* fix test_with which fails on "with mock as ()"
|
msg244215 - (view) |
Author: (flying sheep) * |
Date: 2015-05-27 19:43 |
> isn't it logical?
>
> [] is a mutable data structure
> while () is a immutable data structure
but you don’t assign to data structures, but to names. you *modify* data structures. and in the square bracket assignment syntax you don’t modify the list created by the []. in fact the [] never even create a list.
—————————————————————————————
also it’s news to me that [a, b] = range(2) works!
i always did a, b = range(2), and knew that (a, b) = range(2) works.
but assigning to something looking like a list literal is new and surprising to me. (and i thought i’ve mastered every corner of python’s syntax)
|
msg244227 - (view) |
Author: Alyssa Coghlan (ncoghlan) *  |
Date: 2015-05-28 00:15 |
+1 for Martin's suggestion of removing the inconsistency the other way (i.e. allowing "() = iterable" to mean the same thing as "[] = iterable", effectively asserting that an iterable is empty)
I also agree with Raymond that it doesn't need to be mentioned in the What's New doc, just in the NEWS file.
|
msg245308 - (view) |
Author: Berker Peksag (berker.peksag) *  |
Date: 2015-06-13 09:03 |
Thanks for the reviews. Here is an updated patch.
|
msg246382 - (view) |
Author: Martin Panter (martin.panter) *  |
Date: 2015-07-06 23:20 |
I welcome this patch to go ahead. But the documentation <https://docs.python.org/3.6/reference/simple_stmts.html#assignment-statements> also needs updating (see original post). I think it should mention that “target_list” can be empty. And it should use “iterable” instead of “sequence” in more places.
|
msg264223 - (view) |
Author: Raymond Hettinger (rhettinger) *  |
Date: 2016-04-26 07:15 |
Martin, do you want to take it from here?
|
msg264226 - (view) |
Author: Berker Peksag (berker.peksag) *  |
Date: 2016-04-26 07:40 |
I missed Martin's comment about the documentation. I will update my patch.
|
msg264249 - (view) |
Author: Martin Panter (martin.panter) *  |
Date: 2016-04-26 11:23 |
Okay I’ll let Berker update his patch, but I’m happy to try my hand at updating the documentation if needed.
I reviewed the current patch. I can’t say whether the ast.c change is good or not. But IMO the test would be better off in somewhere like /Lib/test/test_unpack.py. It is only a superficial relationship with tuples because the syntax looks the same. Also may be worth testing that [] = [] etc work as well.
|
msg264811 - (view) |
Author: Berker Peksag (berker.peksag) *  |
Date: 2016-05-04 12:57 |
Here is an updated patch. I moved the test into test_unpack and added additional tests. sequence -> iterable changes should probably be applied to 3.5 as well.
Thanks for the review, Martin.
|
msg265108 - (view) |
Author: Martin Panter (martin.panter) *  |
Date: 2016-05-08 03:10 |
Erm, I think you went overboard with the sequence → iterable changes and subscripting; see the review. Also, I think target_list should be made optional in the grammar description.
|
msg265764 - (view) |
Author: Martin Panter (martin.panter) *  |
Date: 2016-05-17 10:55 |
Hi Berker. I updated your patch according to my comments in the documentation. I hope you don’t mind.
I reverted all the changes about subscripting and slicing an iterable, since this bug is only about assigning to a “target list”.
Actually it is true (despite the current documentation) that you can often assign
sequence[slice] = iterable
But I think that is a separate problem.
|
msg265809 - (view) |
Author: Roundup Robot (python-dev)  |
Date: 2016-05-18 05:44 |
New changeset 8a0754fed986 by Berker Peksag in branch 'default':
Issue #23275: Allow () = iterable assignment syntax
https://hg.python.org/cpython/rev/8a0754fed986
|
msg265811 - (view) |
Author: Berker Peksag (berker.peksag) *  |
Date: 2016-05-18 05:48 |
Thanks Martin. Your edits look much better! :) I will be travelling for PyCon US later this week so I just committed issue23275_v4.diff with minor edits.
|
msg265816 - (view) |
Author: Roundup Robot (python-dev)  |
Date: 2016-05-18 07:19 |
New changeset d3a75daf61e1 by Martin Panter in branch 'default':
Issue #23275: Don’t think this made it into alpha 1
https://hg.python.org/cpython/rev/d3a75daf61e1
|
msg265817 - (view) |
Author: Martin Panter (martin.panter) *  |
Date: 2016-05-18 07:22 |
I just moved the NEWS entry under the alpha 2 heading.
For patches I am going to commit myself, I usually write the NEWS beforehand and remember to adjust it when committing. But perhaps I shouldn’t have done that in this case :)
|
msg267847 - (view) |
Author: Roundup Robot (python-dev)  |
Date: 2016-06-08 13:36 |
New changeset 39a72018dd76 by Martin Panter in branch '3.5':
Issue #23275: Backport target list assignment documentation fixes
https://hg.python.org/cpython/rev/39a72018dd76
New changeset 8700f4d09b28 by Martin Panter in branch '2.7':
Issue #23275: Backport empty square bracket assignment documentation fix
https://hg.python.org/cpython/rev/8700f4d09b28
|
|
Date |
User |
Action |
Args |
2022-04-11 14:58:12 | admin | set | github: 67464 |
2016-06-08 13:36:22 | python-dev | set | messages:
+ msg267847 |
2016-05-18 07:22:20 | martin.panter | set | messages:
+ msg265817 |
2016-05-18 07:19:57 | python-dev | set | messages:
+ msg265816 |
2016-05-18 05:48:24 | berker.peksag | set | status: open -> closed resolution: fixed messages:
+ msg265811
stage: patch review -> resolved |
2016-05-18 05:44:23 | python-dev | set | nosy:
+ python-dev messages:
+ msg265809
|
2016-05-17 10:55:19 | martin.panter | set | files:
+ issue23275_v4.diff
messages:
+ msg265764 |
2016-05-08 03:10:30 | martin.panter | set | messages:
+ msg265108 |
2016-05-04 12:57:56 | berker.peksag | set | files:
+ issue23275_v3.diff type: behavior -> enhancement messages:
+ msg264811
|
2016-04-26 11:23:17 | martin.panter | set | messages:
+ msg264249 |
2016-04-26 07:40:11 | berker.peksag | set | messages:
+ msg264226 |
2016-04-26 07:15:49 | rhettinger | set | assignee: rhettinger -> martin.panter messages:
+ msg264223 |
2015-07-06 23:20:30 | martin.panter | set | messages:
+ msg246382 |
2015-06-13 09:03:46 | berker.peksag | set | files:
+ issue23275_v2.diff
messages:
+ msg245308 |
2015-05-28 03:45:09 | scoder | set | nosy:
+ scoder
|
2015-05-28 00:15:18 | ncoghlan | set | messages:
+ msg244227 |
2015-05-27 19:43:45 | flying sheep | set | nosy:
+ flying sheep messages:
+ msg244215
|
2015-05-27 17:47:39 | rhettinger | set | assignee: rhettinger messages:
+ msg244208 versions:
+ Python 3.6, - Python 3.5 |
2015-05-27 12:53:23 | martin.panter | set | messages:
+ msg244161 |
2015-05-27 12:42:47 | Devin Jeanpierre | set | messages:
+ msg244159 |
2015-05-27 12:28:34 | Rahul Gupta | set | nosy:
+ Rahul Gupta messages:
+ msg244157
|
2015-05-27 12:08:20 | ionelmc | set | nosy:
+ ionelmc
|
2015-04-22 09:42:01 | amaury.forgeotdarc | set | nosy:
+ amaury.forgeotdarc messages:
+ msg241792
|
2015-04-22 09:05:59 | berker.peksag | set | files:
+ issue23275.diff
versions:
+ Python 3.5 keywords:
+ patch nosy:
+ berker.peksag
messages:
+ msg241790 stage: patch review |
2015-04-20 18:28:23 | mark.dickinson | set | nosy:
+ mark.dickinson messages:
+ msg241673
|
2015-04-19 17:57:04 | r.david.murray | set | messages:
+ msg241523 |
2015-04-19 03:34:31 | martin.panter | set | messages:
+ msg241474 |
2015-04-19 02:47:53 | ncoghlan | set | nosy:
+ ncoghlan messages:
+ msg241473
|
2015-03-02 08:14:16 | ezio.melotti | set | nosy:
+ ezio.melotti
|
2015-01-20 10:19:31 | eryksun | set | nosy:
+ eryksun messages:
+ msg234365
|
2015-01-20 09:40:47 | martin.panter | set | nosy:
+ martin.panter messages:
+ msg234364
|
2015-01-20 09:25:19 | Kyle.Buzsaki | set | nosy:
+ Kyle.Buzsaki messages:
+ msg234361
|
2015-01-19 20:12:04 | rhettinger | set | nosy:
+ rhettinger messages:
+ msg234326
|
2015-01-19 19:22:23 | r.david.murray | set | nosy:
+ r.david.murray messages:
+ msg234325
|
2015-01-19 19:16:58 | Cesar.Kawakami | set | nosy:
+ Cesar.Kawakami
|
2015-01-19 19:05:47 | Devin Jeanpierre | create | |