Description
Feature or enhancement
We propose a few improvements and fixes to PEP-657, namely:
- Support underlining errors that span across multiple lines instead of only showing the first line
- Use caret anchors for function calls as well
- 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
- gh-106922: Fix error location for constructs with spaces and parentheses #108959
- [3.12] gh-106922: Fix error location for constructs with spaces and parentheses (GH-108959) #109147
- [3.11] gh-106922: Fix error location for constructs with spaces and parentheses (GH-108959) #109148
- gh-106922: Support multi-line error locations in traceback #109589
- gh-106922: Support multi-line error locations in traceback (attempt 2) #112097