Skip to content

fix(errors): handle parse.ParseError without IndexError in FormatErrorMsg - #1321

Open
jdymitarai wants to merge 1 commit into
google:mainfrom
jdymitarai:fix-parse-error-format
Open

fix(errors): handle parse.ParseError without IndexError in FormatErrorMsg#1321
jdymitarai wants to merge 1 commit into
google:mainfrom
jdymitarai:fix-parse-error-format

Conversation

@jdymitarai

Copy link
Copy Markdown

Summary

Fixes #1303, #1250, #1215, #1256 where YAPF crashed with an unhandled internal IndexError: tuple index out of range whenever parsing raised a parse.ParseError instead of producing a clean error diagnostic.

Cause & Analysis

In yapf/pytree/pytree_utils.py, when parsing fails, ast.parse(code) is executed to check if the snippet is invalid Python syntax (raising SyntaxError). If ast.parse succeeds (for example on newer language constructs or syntax supported by Python's parser but not by the lib2to3 grammar), ParseCodeToTree re-raises parse.ParseError.

When handling this exception in yapf_api.py, FormatErrorMsg(e) attempted to format the error location using e.args[1][0], e.args[1][1], e.args[1][2], assuming e.args[1] was a 3-element tuple (filename, lineno, column). However, _ylib2to3.pgen2.parse.ParseError.args is a 1-tuple ("bad input: ...",) where location metadata is stored in e.context ((prefix, (lineno, column))). This resulted in e.args[1] raising an unhandled IndexError: tuple index out of range instead of reporting the syntax error cleanly.

Solution

  1. Explicitly recognize parse.ParseError in FormatErrorMsg:
    • Extract lineno and column from e.context[1] if available.
    • Extract the error message from e.msg.
  2. Consistently use getattr(e, 'filename', None) across formatters.
  3. Add a safe fallback block in FormatErrorMsg to handle unexpected exception argument shapes cleanly without raising IndexError, TypeError, or AttributeError.
  4. Add unit tests for ParseError formatting and FormatErrorMsg in yapftests/yapf_test.py.

…rMsg

When code raises a parse.ParseError (such as unsupported syntax or grammar mismatches where ast.parse succeeds), FormatErrorMsg attempted to index e.args[1][0], e.args[1][1], e.args[1][2], assuming e.args[1] was a 3-tuple (filename, lineno, column). However, ParseError.args contains ('bad input: ...',) while line and column information are stored in e.context (('', (lineno, column))), resulting in an unhandled IndexError: tuple index out of range.

1. Add explicit support for parse.ParseError in FormatErrorMsg, extracting lineno and column from e.context and the message from e.msg.
2. Use getattr(e, 'filename', None) consistently across error formatters.
3. Add a safe fallback in FormatErrorMsg to handle any unexpected exception structures cleanly without crashing.
4. Add unit tests for ParseError formatting and FormatErrorMsg in yapftests/yapf_test.py.

Fixes google#1303, google#1250, google#1215, google#1256
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug][Crash][Reproducible] IndexError: tuple index out of range

1 participant