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.

classification
Title: starred tuple expression vs list display and function call
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: ezio.melotti, martin.panter, mrabarnett, steven.daprano, umedoblock
Priority: normal Keywords:

Created on 2017-04-16 22:39 by umedoblock, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
x.py umedoblock, 2017-04-16 22:39 simple four lines.
Messages (4)
msg291769 - (view) Author: umedoblock (umedoblock) Date: 2017-04-16 22:39
Hi, all.

First of all, my python environment is below.

Python 3.5.2+ (default, Sep 22 2016, 12:18:14) 
[GCC 6.2.0 20160927] on linux

= differ evaluation order about starred expression
I get below result then I run x.py
======================================================
  File "/home/umedoblock/x.py", line 4
    (*(1, 2))
    ^
SyntaxError: can't use starred expression here
======================================================

Next, I comment out line 4 and run Python3.
I got below result.
And I feel strange behavior above result.
Because I think that Python should return same result above and below. 
======================================================
Traceback (most recent call last):
  File "/home/umedoblock/x.py", line 1, in <module>
    list(*(1, 2))
TypeError: list() takes at most 1 argument (2 given)
======================================================

= pass or not about starred expression.
list expression pass starred expression, the other hand
tuple expression cannot pass starred expression.
I hope to pass starred expression about list and tuple.
>>> [*(1, 2)]
[1, 2]
>>> (*(1, 2))
  File "<stdin>", line 1
SyntaxError: can't use starred expression here
msg291770 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2017-04-17 00:01
This doesn’t seem like a bug to me. At least it is consistent with the rule for making a tuple when there are commas versus returning the direct expression when there are no commas:

>>> x = (1); type(x)
<class 'int'>
>>> x = (1,); type(x)
<class 'tuple'>

I don’t think it is worth changing the syntax again just to pack a single starred expression into a tuple without a comma. If you really want to do that, it would be clearer to write

expression = (1, 2)
tuple_1 = (*expression,)  # Brackets and comma suggest a tuple
tuple_2 = tuple(expression)  # Tuple constructor even more obvious

Allowing tuple packing without a comma would add a new inconsistency with function calls. It would conflict with your list(*(1, 2)) case:

list(*(1, 2))  # Currently equivalent to list(1, 2)
list( (*(1, 2)) )  # Would be equivalent to list( (1, 2) )

The root problem IMO is that round brackets and commas have too many inconsistent special cases in Python (simple expressions vs tuples, tuples with zero, one or more items, function calls and signatures, generator expressions, unpacking assignments, etc). But it may be too hard to change any of this.
msg291772 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2017-04-17 01:12
> list expression pass starred expression, the other hand
> tuple expression cannot pass starred expression.

You are misinterpreting what you are seeing.

( ) is not a tuple expression (except for the special case of empty brackets, which makes an empty tuple). It's just grouping an expression. So (*x) is equivalent to just bare *x.

To make a tuple, you need a comma.

Apart from the empty tuple, the brackets are just for grouping. Put a comma after the starred expression and it will work:

py> t = 1, 2
py> t
(1, 2)
py> (*t,)
(1, 2)


The trailing comma is allowed in lists as well:

py> [*t,]
[1, 2]


I agree with Martin: there's no bug here, the behaviour is consistent with the way tuples and lists are normally created, and there's no need to make (*t) yet another special case.

If you really want to argue in favour of this change, I suggest you discuss it on the Python-Ideas mailing list and see if you can get community consensus for it. *If* you get agreement that this is a good idea, then you can re-open this.
msg291779 - (view) Author: umedoblock (umedoblock) Date: 2017-04-17 04:39
Sorry and thanks to Martin and Steven.
I agree with your post about first my post.
I understand "(*x) is equivalent to just bare *x."
History
Date User Action Args
2022-04-11 14:58:45adminsetgithub: 74270
2017-04-17 04:39:31umedoblocksetmessages: + msg291779
2017-04-17 01:12:49steven.dapranosetstatus: open -> closed

nosy: + steven.daprano
messages: + msg291772

resolution: not a bug
stage: resolved
2017-04-17 00:01:11martin.pantersettitle: about starred expression -> starred tuple expression vs list display and function call
nosy: + martin.panter

messages: + msg291770

components: + Interpreter Core, - Regular Expressions
2017-04-16 22:39:03umedoblockcreate