How did print(*a, a.pop(0)) change?

I suspect this may have been an accident, though I prefer the new behavior.

The new behavior is a consequence of a change to how the bytecode for * arguments works. The change is in the changelog under Python 3.9.0 alpha 3:

bpo-39320: Replace four complex bytecodes for building sequences with three simpler ones.

The following four bytecodes have been removed:

  • BUILD_LIST_UNPACK
  • BUILD_TUPLE_UNPACK
  • BUILD_SET_UNPACK
  • BUILD_TUPLE_UNPACK_WITH_CALL

The following three bytecodes have been added:

  • LIST_TO_TUPLE
  • LIST_EXTEND
  • SET_UPDATE

On Python 3.8, the bytecode for f(*a, a.pop()) looks like this:

  1           0 LOAD_NAME                0 (f)
              2 LOAD_NAME                1 (a)
              4 LOAD_NAME                1 (a)
              6 LOAD_METHOD              2 (pop)
              8 CALL_METHOD              0
             10 BUILD_TUPLE              1
             12 BUILD_TUPLE_UNPACK_WITH_CALL     2
             14 CALL_FUNCTION_EX         0
             16 RETURN_VALUE

while on 3.9, it looks like this:

  1           0 LOAD_NAME                0 (f)
              2 BUILD_LIST               0
              4 LOAD_NAME                1 (a)
              6 LIST_EXTEND              1
              8 LOAD_NAME                1 (a)
             10 LOAD_METHOD              2 (pop)
             12 CALL_METHOD              0
             14 LIST_APPEND              1
             16 LIST_TO_TUPLE
             18 CALL_FUNCTION_EX         0
             20 RETURN_VALUE

In the old bytecode, the code pushes a and (a.pop(),) onto the stack, then unpacks those two iterables into a tuple. In the new bytecode, the code pushes a list onto the stack, then does l.extend(a) and l.append(a.pop()), then calls tuple(l).

This change has the effect of shifting the unpacking of a to before the pop call, but this doesn’t seem to have been deliberate. Looking at bpo-39320, the intent was to simplify the bytecode instructions, not to change the behavior, and the bpo thread has no discussion of behavior changes.

Leave a Comment

tech