Hi everyone, I recently unintentionally changed the semantics of this expression `[print("a"), *None, print("b")]`. PEP 448 states that this should raise an exception, but does not specify evaluation order. My implementation was based on the general principle that evaluation in Python is left to right unless specified otherwise. The question is, what should
[print("a"), *None, print("b")]
Commits 13bc139 and 8a4cd70 introduced subtle changes in the evaluation logic of unpacking operations. Previously, all elements were evaluated prior to being collected in a container. Now, these operations are interleaved. For example, the code `[*a, *b]` used to evaluate in the order `a` -> `b` -> `a.__iter__()` -> `b.__iter__()`. Now, it evaluates as `a` -> `a.__iter__()` -> `b` -> `b.__iter__()`.
I believe this breaking semantic change is a bug, and I've opened a PR to fix it (https://github.com/python/cpython/pull/18264). My reasoning is that "unary *" isn't an operator; it doesn't appear on the operator precedence table in the docs, and you can't evaluate `*x`. Like the brackets and the comma, it's part of the syntax of the outer display expression, not the inner one. It specifies how the list should be built, so it should be evaluated last, as part of the list construction. And it has always been this way since PEP 448 (as far as I can tell). The lack of explicitly listed precedence for an operator does not mean
print before raising an exception? I think just "a", Brandt thinks "a" and "b". Brandt argues that I have introduced a bug. I think I have fixed one, admittedly one that I didn't previously realize existed. There is a precedent for fixing evaluation order to be left to right: https://bugs.python.org/issue29652 On 06/02/2020 6:28 am, Brandt Bucher wrote: that it isn't an operator, merely that it doesn't need precedence due to the grammar. For example the slice creation operator `x:y` in `a[x:y]` needs no precedence as it is constrained to only occur in indexing operations. Likewise the unpacking operation `*a` can only occur in certain expressions. That doesn't mean that is not an operation.
The docs themselves seem to support this line of reasoning (https://docs.python.org/3/reference/expressions.html#evaluation-order):
In the following lines, expressions will be evaluated in the arithmetic order of their suffixes: ... expr1(expr2, expr3, *expr4, **expr5)
Note that the stars are not part of expressions 1-5, but are a part of the top-level call expression that operates on them all.
There are many layers of grammar that make up a call. It is entirely arbitrary what you call an expression or some other grammatical entity. `*expr4` is parsed as an argument, the same as `expr2`. Cheers, Mark.
Mark Shannon disagrees with me (I'll let him reply rather than attempt to summarize his argument for him), but we figured it might be better to get more input here on exactly whether you all think the behavior should change or not. You can see the discussion on the PR itself for some additional points and context.
Thanks!
Brandt _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/4HS2ZEQW... Code of Conduct: http://python.org/psf/codeofconduct/