On Thu, 6 Feb 2020 at 20:17, Mark Shannon <mark@hotpy.org> wrote:
>
> 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")]
>
> 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.
I think that if this were a new feature, either order would be
arguable. But given that this code previously printed "a b", I think
that changing the order is a change in user-visible behaviour and
therefore the existing behaviour should be preserved (certainly in
bugfix releases).
> There is a precedent for fixing evaluation order to be left to right:
> https://bugs.python.org/issue29652
Changing the order as part of a feature release, listing it as a
user-visible behaviour change in "What's New" seems acceptable to me.
But characterising this change as a bug fix doesn't.
> On 06/02/2020 6:28 am, Brandt Bucher wrote:
> > 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).
I agree that it's the *change in behaviour* that's the issue here. We
should fix that (by reverting to 3.8.1 behaviour) before 3.8.2 gets
released.
> The lack of explicitly listed precedence for an operator does not mean
> 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.
I don't think this is a particularly helpful way of looking at it. I
don't think there's any particular need here to try to argue that
either behaviour is "right" or "wrong". The previous behaviour has
been round for some time, and the change in behaviour was (by your own
admission) inadvertent. Therefore it seems obvious to me that the
reasonable thing to do is to apply Brandt's PR, that restores the old
evaluation order (with the *intended* fix from your patch intact, as I
understand it). If, once this has been done, you still care strongly
enough to argue for a behaviour change, targeted at 3.9 (assuming
no-one insists on a deprecation period for the change!), then that's
fine. Personally I think the arguments either way are weak, and I'd be
inclined not to care, or to mildly prefer not bothering, in such a
debate - but let's have the debate once the pressure of "is it OK to
do this in a bugfix release?" has been removed.
Paul
_______________________________________________
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/SUIATL7A7M2P3YWYIVIWP5EAM7NRZ5D3/
Code of Conduct: http://python.org/psf/codeofconduct/