packing unpacking depends on order.

Ian Kelly ian.g.kelly at gmail.com
Thu Sep 3 05:32:39 CEST 2015


On Sep 2, 2015 7:51 PM, "Steven D'Aprano" <steve at pearwood.info> wrote:
>
> What's the alternative? I asked this question earlier, and got no answer --
> apparently at least three people prefer behaviour that they cannot explain
> how to get the results they want :-)
>
> As far as I am concerned, having both of these:
>
>     b, a[b] = a[b], b
>     a[b], b = b, a[b]
>
> result in the same bindings is not only hard to implement, but hard to
> explain and hard to think about. Try to write an algorithm that gives the
> result you want,

I don't think it's really all that difficult.

1) Evaluate the RHS from left to right as is already done, collecting
the values to be assigned.

2) Evaluate the LHS from left to right. Note there are only three
different types of assignments: assignments to names, assignments to
attributes (i.e. using __setattr__), and assignments to items (i.e.
using __setitem__).

a) For assignments to names, there is nothing to evaluate.

b) For assignments to attributes, the expression to the left of the .
must be evaluated and stored.

c) For assignments to items, the expression before the square brackets
and the expression inside the square brackets must be evaluated
(probably in that order, although it doesn't much matter as long as
it's consistent) and stored.

3) Perform the assignments, again from left to right.

There can still be ordering effects, e.g. if you do a, b.c = d, e and
b's __setattr__ references a, or if one of the expressions has side
effects. The same is also true on the RHS, as it is today. I'm not
really concerned with that possibility.

> one which supports all the cases including the case where
> one or both of a and b don't exist prior to the assignments.

That's a red herring. If either a or b don't exist prior to the
assignments, then the result of assigning to a[b] *should* be an
error.


More information about the Python-list mailing list