Search code examples
pythonpython-3.xnumpynumpy-slicing

Why is unpacking a list in indexing a syntax error in Python 3.8 but not Python 3.12?


The following code

import numpy as np
x = np.arange(32).reshape(2,2,2,2,2)
extra = [1 for _ in range(3)]
print(x[*extra, 0, 0])

prints 28 as expected in Python 3.12 but results in the syntax error

  File "main.py", line 4
    print(x[*extra, 0, 0])
            ^
SyntaxError: invalid syntax

in Python 3.8.

Replacing the indexing with print(x[(*extra, 0, 0)]) works in both versions.

The NumPy documentation states that the offending line is syntax sugar for the working one, so I do not understand why there is a syntax error.

A quick search for the terms "unpack","index", and "getitem" for the versions 3.9 to 3.12 (inclusive) on https://docs.python.org/3/whatsnew/index.html didn't turn up any indication that there was a change to indexing or unpacking syntax, although I may have missed something. The closest I found was that Python 3.11 has the change "Starred unpacking expressions can now be used in for statements."


Solution

  • This was a consequence of grammar changes in PEP 646 – Variadic Generics and somehow didn't get a mention in the changelog for 3.11.

    Minimal reproducer:

    $ python3.11 -c 'print({():42}[*()])'
    42
    $ python3.10 -c 'print({():42}[*()])'
      File "<string>", line 1
        print({():42}[*()])
              ^^^^^^^^^^^^
    SyntaxError: invalid syntax. Perhaps you forgot a comma?
    

    The relevant diff can be found at #31018: Implement PEP 646 grammar changes.