How did we move from [*a,...] to print(*a,...)? They are quite different.

On Thu, Feb 6, 2020 at 14:07 Serhiy Storchaka <storch...@gmail.com> wrote:

> 06.02.20 08:28, Brandt Bucher пише:
> > 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 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.
> >
> > 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.
>
> I have two problems with this change.
>
> 1. It changes error messages.
>
>  >>> print(*1)
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: print() argument after * must be an iterable, not int
>  >>> print(*1, *2)
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: Value after * must be an iterable, not int
>
> In 3.8 you got the same error message.
>
>  >>> print(*1)
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: print() argument after * must be an iterable, not int
>  >>> print(*1, *2)
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: print() argument after * must be an iterable, not int
>
> I am not sure whether the function name is a useful information, but
> some effort was spend to preserve it. In any case, error messages should
> be consistent.
>
>
> 2. It introduces performance regression.
>
> In 3.8 the bytecode for `(*a, *b, *c)` was:
>
>    1           0 LOAD_NAME                0 (a)
>                2 LOAD_NAME                1 (b)
>                4 LOAD_NAME                2 (c)
>                6 BUILD_TUPLE_UNPACK       3
>
> In master it is:
>
>    1           0 BUILD_LIST               0
>                2 LOAD_NAME                0 (a)
>                4 LIST_EXTEND              1
>                6 LOAD_NAME                1 (b)
>                8 LIST_EXTEND              1
>               10 LOAD_NAME                2 (c)
>               12 LIST_EXTEND              1
>               14 LIST_TO_TUPLE
>
> The bytecode is larger, therefore slower. It also prevents possible
> optimization of BUILD_TUPLE_UNPACK and similar opcodes for common case
> of tuples and lists which would allow to minimize the number of memory
> allocations.
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@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/CZZKWFW22TBJ5VLO7GUIF7A7QBFTBAC2/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-- 
--Guido (mobile)
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@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/PVCX2G6FJFCTW2P7D27UM76AAGSDJAT3/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to