On Wed, May 23, 2018 at 1:22 AM, Ian Kelly <ian.g.ke...@gmail.com> wrote: > On Tue, May 22, 2018 at 8:25 AM, Chris Angelico <ros...@gmail.com> wrote: >> On Tue, May 22, 2018 at 8:25 PM, bartc <b...@freeuk.com> wrote: >>> Note that Python tuples don't always need a start symbol: >>> >>> a = 10,20,30 >>> >>> assigns a tuple to a. >> >> The tuple has nothing to do with the parentheses, except for the >> special case of the empty tuple. It's the comma. > > Although, if the rule were really as simple as "commas make tuples", > then this would be a list containing a tuple: [1, 2, 3].
In an arbitrary expression, a comma between two expressions creates a tuple. In other contexts, the comma has other meanings, which take precedence: * Separating a function's arguments (both at definition and call) * Enumerating import targets and global/nonlocal names * Separating an assertion from its message * Listing multiple context managers * And probably some that I've forgotten. In those contexts, you can override the normal interpretation and force the tuple by using parentheses, preventing it from being parsed as something else, and making it instead a single expression: print((1, 2)) # prints a tuple print(1, 2) # prints two items The comma is what makes the tuple, though, not the parentheses. The parentheses merely prevent this from being something else. > Curiously, parentheses are also sometimes required for iterable > unpacking. For example: > > py> 1, 2, *range(3,5) > (1, 2, 3, 4) > py> d = {} > py> d[1, 2] = 42 > py> d[1, 2, *range(3,5)] = 43 > File "<stdin>", line 1 > d[1, 2, *range(3,5)] = 43 > ^ > SyntaxError: invalid syntax I'm not sure what you mean about the parentheses here. AIUI iterable unpacking simply isn't supported inside subscripting. If that's an actual problem anywhere, I'm sure it could be added :) > py> def foo(): > ... return 1, 2 > ... > py> foo() > (1, 2) > > py> def foo(): > ... return 1, 2, *range(3, 5) > File "<stdin>", line 2 > return 1, 2, *range(3, 5) > ^ > SyntaxError: invalid syntax That's a slightly curious case, since it's definitely being parsed the same way. PEP 448 gives precedence for adding this sort of thing, if anyone feels like digging into it. You may find that there's some ambiguity somewhere in the unparenthesized version. > py> def foo(): > ... yield 1, 2 > ... > py> list(foo()) > [(1, 2)] > py> def foo(): > ... yield 1, 2, *range(3, 5) > File "<stdin>", line 2 > yield 1, 2, *range(3, 5) > ^ > SyntaxError: invalid syntax That's the exact same thing as the 'return' example, so it'll behave the same way. > py> for x in 1, 2: print(x) > ... > 1 > 2 > py> for x in 1, 2, *range(3, 5): print(x) > File "<stdin>", line 1 > for x in 1, 2, *range(3, 5): print(x) > ^ > SyntaxError: invalid syntax In fact, I think probably all four of your examples would behave the same way. So if you want to push for the change, go for it :) ChrisA -- https://mail.python.org/mailman/listinfo/python-list