Skip to content

Support multi-line error locations in traceback and other related improvements (PEP-657, 3.11) #106922

@williamwen42

Description

@williamwen42

Feature or enhancement

We propose a few improvements and fixes to PEP-657, namely:

  1. Support underlining errors that span across multiple lines instead of only showing the first line
  2. Use caret anchors for function calls as well
  3. Fix bracket/binary op heuristic in the caret anchor computation function

Pitch

We already implemented these items in PyTorch here: pytorch/pytorch#104676. We're seeing if these may be worth adding to CPython.

Rationale for 1

Multi-line expressions can negate the utility of PEP-657, for example:

really_long_expr_1 = 1
really_long_expr_2 = 2
really_long_expr_3 = 0
really_long_expr_4 = 4

y = (
    (
        really_long_expr_1 +
        really_long_expr_2
    ) /
    really_long_expr_2 /
    really_long_expr_3
)

Current traceback:

Traceback (most recent call last):
  File "/scratch/williamwen/work/pytorch/playground5.py", line 25, in <module>
    (
ZeroDivisionError: float division by zero

Better traceback:

Traceback (most recent call last):
  File "/scratch/williamwen/work/pytorch/playground5.py", line 25, in <module>
    (
    ~
        really_long_expr_1 +
        ~~~~~~~~~~~~~~~~~~~~
        really_long_expr_2
        ~~~~~~~~~~~~~~~~~~
    ) /
    ~~^
    really_long_expr_2 /
    ~~~~~~~~~~~~~~~~~~
ZeroDivisionError: float division by zero

Rationale for 2

Helpful for identifying function calls that cause errors in chained function calls. We may as well do it since we're already doing it for subscripts. For example:

def f1(x1):
    def f2(x2):
        raise RuntimeError()
    return f2
y = f1(1)(2)(3)

Current traceback:

Traceback (most recent call last):
  File "/scratch/williamwen/work/pytorch/playground5.py", line 22, in <module>
    y = f1(1)(2)(3)
        ^^^^^^^^
  File "/scratch/williamwen/work/pytorch/playground5.py", line 6, in f2
    raise RuntimeError()
RuntimeError

Better traceback:

Traceback (most recent call last):
  File "/scratch/williamwen/work/pytorch/playground5.py", line 22, in <module>
    y = f1(1)(2)(3)
        ~~~~~^^^
  File "/scratch/williamwen/work/pytorch/playground5.py", line 6, in f2
    raise RuntimeError()
RuntimeError

Rationale for 3

The binary op anchors are computed by taking the next non-space character after the left subexpression. This is incorrect in some simple cases:

    x = (3) / 0
        ~~^~~~~
ZeroDivisionError: division by zero

We should expect

    x = (3) / 0
        ~~~~^~~
ZeroDivisionError: division by zero

The fix is that we should continue advancing the anchor until we find a non-space character that is also not in )\# (for \#, we should move the anchor to the next line).

Subscript has a similar issue as well. We should continue advancing the left anchor until we find [, and the right anchor should be the end of the entire subscript expression.

cc @pablogsal @isidentical @ammaraskar @iritkatriel @ezyang

Linked PRs

Metadata

Metadata

Assignees

Labels

interpreter-core(Objects, Python, Grammar, and Parser dirs)type-featureA feature request or enhancement

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    pFad - Phonifier reborn

    Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

    Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


    Alternative Proxies:

    Alternative Proxy

    pFad Proxy

    pFad v3 Proxy

    pFad v4 Proxy