Skip to content

3.14 parser silently accepts invalid except-clause syntax 'except A, B:' (Python-2 form, SyntaxError on 3.0-3.13) #158260

Description

@jbdevprimary

Repro

try:
    pass
except OSError, ValueError:
    pass
$ python3.14 -c "import ast; ast.parse(open('repro.py').read())"
# no error — parses successfully

Confirmed via disassembly that it compiles to the SAME bytecode as the correct except (OSError, ValueError): form (BUILD_TUPLE + CHECK_EXC_MATCH) — not the Python-2 except Type, name: binding semantics, which would be a different and even more dangerous silent misinterpretation. So functionally the 3.14 parser is currently treating an omitted-parens exception-type list as equivalent to a parenthesized tuple.

$ python3.12 -c "import ast; ast.parse(open('repro.py').read())"
  File "<unknown>", line 3
    except OSError, ValueError:
           ^^^^^^^^^^^^^^^^^^^
SyntaxError: multiple exception types must be parenthesized

3.9, 3.12, and 3.13 (tested on this machine) all correctly raise SyntaxError: multiple exception types must be parenthesized (added by bpo-32892 / the PEG parser's dedicated error message for this exact Python-2 leftover). Only 3.14 accepts it.

Reproduced across independent 3.14 builds

  • Homebrew python@3.14 3.14.6 (macOS arm64)
  • uv's managed cpython-3.14.0-macos-aarch64-none (python-build-standalone)
  • asdf-installed 3.14.4
  • Official python:3.14-slim Docker Hub image, 3.14.7 (python:3.14-slim, pulled fresh, Linux/GCC build) — rules out anything specific to this machine or macOS

All four reproduce identically.

Why this matters

This isn't purely cosmetic: ruff format (astral-sh/ruff#28928, filed as a companion issue) appears to exploit this leniency when targeting py314, actively rewriting valid except (A, B): into the unparenthesized form — producing code that is a SyntaxError on every Python version except 3.14. A tool or codebase relying on 3.14's leniency here will silently produce code broken everywhere else.

Expected

except A, B: (without parentheses, 2+ types) should continue to raise SyntaxError: multiple exception types must be parenthesized on 3.14 as it does on every prior Python 3 version, unless this is an intentional, documented grammar change for 3.14 (in which case apologies for the noise, and a pointer to the relevant PEP/what's-new entry would be very welcome — I could not find one).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions