# 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: https://github.com/pytorch/pytorch/pull/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: ```python 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: ```python 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 <!-- gh-linked-prs --> ### Linked PRs * gh-108959 * gh-109147 * gh-109148 * gh-109589 * gh-112097 <!-- /gh-linked-prs -->