This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2015年01月19日 19:05 by Devin Jeanpierre, last changed 2022年04月11日 14:58 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| issue23275.diff | berker.peksag, 2015年04月22日 09:05 | review | ||
| issue23275_v2.diff | berker.peksag, 2015年06月13日 09:03 | review | ||
| issue23275_v3.diff | berker.peksag, 2016年05月04日 12:57 | review | ||
| issue23275_v4.diff | martin.panter, 2016年05月17日 10:55 | review | ||
| Messages (31) | |||
|---|---|---|---|
| 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) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | 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) * (Python triager) | 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) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | Date: 2015年06月13日 09:03 | |
Thanks for the reviews. Here is an updated patch. |
|||
| msg246382 - (view) | Author: Martin Panter (martin.panter) * (Python committer) | 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) * (Python committer) | Date: 2016年04月26日 07:15 | |
Martin, do you want to take it from here? |
|||
| msg264226 - (view) | Author: Berker Peksag (berker.peksag) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | 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) * (Python committer) | 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) (Python triager) | 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) * (Python committer) | 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) (Python triager) | 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) * (Python committer) | 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) (Python triager) | 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 |
|||
| History | |||
|---|---|---|---|
| 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 | |