mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
gh-99180: Remove traceback anchors in return and assign statements that cover all the displayed range (#112670)
This commit is contained in:
parent
c1bf4874c1
commit
4a08a75cf4
3 changed files with 240 additions and 33 deletions
|
@ -695,7 +695,6 @@ class TracebackErrorLocationCaretTestBase:
|
||||||
' ~~~~~~~~^^\n'
|
' ~~~~~~~~^^\n'
|
||||||
f' File "{__file__}", line {lineno_f+2}, in f_with_multiline\n'
|
f' File "{__file__}", line {lineno_f+2}, in f_with_multiline\n'
|
||||||
' return compile(code, "?", "exec")\n'
|
' return compile(code, "?", "exec")\n'
|
||||||
' ~~~~~~~^^^^^^^^^^^^^^^^^^^\n'
|
|
||||||
' File "?", line 7\n'
|
' File "?", line 7\n'
|
||||||
' foo(a, z\n'
|
' foo(a, z\n'
|
||||||
' ^'
|
' ^'
|
||||||
|
@ -785,8 +784,8 @@ class TracebackErrorLocationCaretTestBase:
|
||||||
def test_caret_for_binary_operators_with_spaces_and_parenthesis(self):
|
def test_caret_for_binary_operators_with_spaces_and_parenthesis(self):
|
||||||
def f_with_binary_operator():
|
def f_with_binary_operator():
|
||||||
a = 1
|
a = 1
|
||||||
b = ""
|
b = c = ""
|
||||||
return ( a ) +b
|
return ( a ) +b + c
|
||||||
|
|
||||||
lineno_f = f_with_binary_operator.__code__.co_firstlineno
|
lineno_f = f_with_binary_operator.__code__.co_firstlineno
|
||||||
expected_error = (
|
expected_error = (
|
||||||
|
@ -795,7 +794,7 @@ class TracebackErrorLocationCaretTestBase:
|
||||||
' callable()\n'
|
' callable()\n'
|
||||||
' ~~~~~~~~^^\n'
|
' ~~~~~~~~^^\n'
|
||||||
f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n'
|
f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n'
|
||||||
' return ( a ) +b\n'
|
' return ( a ) +b + c\n'
|
||||||
' ~~~~~~~~~~^~\n'
|
' ~~~~~~~~~~^~\n'
|
||||||
)
|
)
|
||||||
result_lines = self.get_exception(f_with_binary_operator)
|
result_lines = self.get_exception(f_with_binary_operator)
|
||||||
|
@ -983,7 +982,7 @@ class TracebackErrorLocationCaretTestBase:
|
||||||
def f2(b):
|
def f2(b):
|
||||||
raise RuntimeError("fail")
|
raise RuntimeError("fail")
|
||||||
return f2
|
return f2
|
||||||
return f1("x")("y")
|
return f1("x")("y")("z")
|
||||||
|
|
||||||
lineno_f = f_with_call.__code__.co_firstlineno
|
lineno_f = f_with_call.__code__.co_firstlineno
|
||||||
expected_error = (
|
expected_error = (
|
||||||
|
@ -992,7 +991,7 @@ class TracebackErrorLocationCaretTestBase:
|
||||||
' callable()\n'
|
' callable()\n'
|
||||||
' ~~~~~~~~^^\n'
|
' ~~~~~~~~^^\n'
|
||||||
f' File "{__file__}", line {lineno_f+5}, in f_with_call\n'
|
f' File "{__file__}", line {lineno_f+5}, in f_with_call\n'
|
||||||
' return f1("x")("y")\n'
|
' return f1("x")("y")("z")\n'
|
||||||
' ~~~~~~~^^^^^\n'
|
' ~~~~~~~^^^^^\n'
|
||||||
f' File "{__file__}", line {lineno_f+3}, in f2\n'
|
f' File "{__file__}", line {lineno_f+3}, in f2\n'
|
||||||
' raise RuntimeError("fail")\n'
|
' raise RuntimeError("fail")\n'
|
||||||
|
@ -1507,6 +1506,184 @@ class TracebackErrorLocationCaretTestBase:
|
||||||
' raise MemoryError()']
|
' raise MemoryError()']
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
def test_anchors_for_simple_return_statements_are_elided(self):
|
||||||
|
def g():
|
||||||
|
1/0
|
||||||
|
|
||||||
|
def f():
|
||||||
|
return g()
|
||||||
|
|
||||||
|
result_lines = self.get_exception(f)
|
||||||
|
expected = ['Traceback (most recent call last):',
|
||||||
|
f" File \"{__file__}\", line {self.callable_line}, in get_exception",
|
||||||
|
" callable()",
|
||||||
|
" ~~~~~~~~^^",
|
||||||
|
f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f",
|
||||||
|
" return g()",
|
||||||
|
f" File \"{__file__}\", line {g.__code__.co_firstlineno + 1}, in g",
|
||||||
|
" 1/0",
|
||||||
|
" ~^~"
|
||||||
|
]
|
||||||
|
self.assertEqual(result_lines, expected)
|
||||||
|
|
||||||
|
def g():
|
||||||
|
1/0
|
||||||
|
|
||||||
|
def f():
|
||||||
|
return g() + 1
|
||||||
|
|
||||||
|
result_lines = self.get_exception(f)
|
||||||
|
expected = ['Traceback (most recent call last):',
|
||||||
|
f" File \"{__file__}\", line {self.callable_line}, in get_exception",
|
||||||
|
" callable()",
|
||||||
|
" ~~~~~~~~^^",
|
||||||
|
f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f",
|
||||||
|
" return g() + 1",
|
||||||
|
" ~^^",
|
||||||
|
f" File \"{__file__}\", line {g.__code__.co_firstlineno + 1}, in g",
|
||||||
|
" 1/0",
|
||||||
|
" ~^~"
|
||||||
|
]
|
||||||
|
self.assertEqual(result_lines, expected)
|
||||||
|
|
||||||
|
def g(*args):
|
||||||
|
1/0
|
||||||
|
|
||||||
|
def f():
|
||||||
|
return g(1,
|
||||||
|
2, 4,
|
||||||
|
5)
|
||||||
|
|
||||||
|
result_lines = self.get_exception(f)
|
||||||
|
expected = ['Traceback (most recent call last):',
|
||||||
|
f" File \"{__file__}\", line {self.callable_line}, in get_exception",
|
||||||
|
" callable()",
|
||||||
|
" ~~~~~~~~^^",
|
||||||
|
f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f",
|
||||||
|
" return g(1,",
|
||||||
|
" 2, 4,",
|
||||||
|
" 5)",
|
||||||
|
f" File \"{__file__}\", line {g.__code__.co_firstlineno + 1}, in g",
|
||||||
|
" 1/0",
|
||||||
|
" ~^~"
|
||||||
|
]
|
||||||
|
self.assertEqual(result_lines, expected)
|
||||||
|
|
||||||
|
def g(*args):
|
||||||
|
1/0
|
||||||
|
|
||||||
|
def f():
|
||||||
|
return g(1,
|
||||||
|
2, 4,
|
||||||
|
5) + 1
|
||||||
|
|
||||||
|
result_lines = self.get_exception(f)
|
||||||
|
expected = ['Traceback (most recent call last):',
|
||||||
|
f" File \"{__file__}\", line {self.callable_line}, in get_exception",
|
||||||
|
" callable()",
|
||||||
|
" ~~~~~~~~^^",
|
||||||
|
f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f",
|
||||||
|
" return g(1,",
|
||||||
|
" ~^^^",
|
||||||
|
" 2, 4,",
|
||||||
|
" ^^^^^",
|
||||||
|
" 5) + 1",
|
||||||
|
" ^^",
|
||||||
|
f" File \"{__file__}\", line {g.__code__.co_firstlineno + 1}, in g",
|
||||||
|
" 1/0",
|
||||||
|
" ~^~"
|
||||||
|
]
|
||||||
|
self.assertEqual(result_lines, expected)
|
||||||
|
|
||||||
|
def test_anchors_for_simple_assign_statements_are_elided(self):
|
||||||
|
def g():
|
||||||
|
1/0
|
||||||
|
|
||||||
|
def f():
|
||||||
|
x = g()
|
||||||
|
|
||||||
|
result_lines = self.get_exception(f)
|
||||||
|
expected = ['Traceback (most recent call last):',
|
||||||
|
f" File \"{__file__}\", line {self.callable_line}, in get_exception",
|
||||||
|
" callable()",
|
||||||
|
" ~~~~~~~~^^",
|
||||||
|
f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f",
|
||||||
|
" x = g()",
|
||||||
|
f" File \"{__file__}\", line {g.__code__.co_firstlineno + 1}, in g",
|
||||||
|
" 1/0",
|
||||||
|
" ~^~"
|
||||||
|
]
|
||||||
|
self.assertEqual(result_lines, expected)
|
||||||
|
|
||||||
|
def g(*args):
|
||||||
|
1/0
|
||||||
|
|
||||||
|
def f():
|
||||||
|
x = g(1,
|
||||||
|
2, 3,
|
||||||
|
4)
|
||||||
|
|
||||||
|
result_lines = self.get_exception(f)
|
||||||
|
expected = ['Traceback (most recent call last):',
|
||||||
|
f" File \"{__file__}\", line {self.callable_line}, in get_exception",
|
||||||
|
" callable()",
|
||||||
|
" ~~~~~~~~^^",
|
||||||
|
f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f",
|
||||||
|
" x = g(1,",
|
||||||
|
" 2, 3,",
|
||||||
|
" 4)",
|
||||||
|
f" File \"{__file__}\", line {g.__code__.co_firstlineno + 1}, in g",
|
||||||
|
" 1/0",
|
||||||
|
" ~^~"
|
||||||
|
]
|
||||||
|
self.assertEqual(result_lines, expected)
|
||||||
|
|
||||||
|
def g():
|
||||||
|
1/0
|
||||||
|
|
||||||
|
def f():
|
||||||
|
x = y = g()
|
||||||
|
|
||||||
|
result_lines = self.get_exception(f)
|
||||||
|
expected = ['Traceback (most recent call last):',
|
||||||
|
f" File \"{__file__}\", line {self.callable_line}, in get_exception",
|
||||||
|
" callable()",
|
||||||
|
" ~~~~~~~~^^",
|
||||||
|
f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f",
|
||||||
|
" x = y = g()",
|
||||||
|
" ~^^",
|
||||||
|
f" File \"{__file__}\", line {g.__code__.co_firstlineno + 1}, in g",
|
||||||
|
" 1/0",
|
||||||
|
" ~^~"
|
||||||
|
]
|
||||||
|
self.assertEqual(result_lines, expected)
|
||||||
|
|
||||||
|
def g(*args):
|
||||||
|
1/0
|
||||||
|
|
||||||
|
def f():
|
||||||
|
x = y = g(1,
|
||||||
|
2, 3,
|
||||||
|
4)
|
||||||
|
|
||||||
|
result_lines = self.get_exception(f)
|
||||||
|
expected = ['Traceback (most recent call last):',
|
||||||
|
f" File \"{__file__}\", line {self.callable_line}, in get_exception",
|
||||||
|
" callable()",
|
||||||
|
" ~~~~~~~~^^",
|
||||||
|
f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f",
|
||||||
|
" x = y = g(1,",
|
||||||
|
" ~^^^",
|
||||||
|
" 2, 3,",
|
||||||
|
" ^^^^^",
|
||||||
|
" 4)",
|
||||||
|
" ^^",
|
||||||
|
f" File \"{__file__}\", line {g.__code__.co_firstlineno + 1}, in g",
|
||||||
|
" 1/0",
|
||||||
|
" ~^~"
|
||||||
|
]
|
||||||
|
self.assertEqual(result_lines, expected)
|
||||||
|
|
||||||
|
|
||||||
@requires_debug_ranges()
|
@requires_debug_ranges()
|
||||||
class PurePythonTracebackErrorCaretTests(
|
class PurePythonTracebackErrorCaretTests(
|
||||||
|
@ -1701,7 +1878,7 @@ class TracebackFormatMixin:
|
||||||
# Check a known (limited) number of recursive invocations
|
# Check a known (limited) number of recursive invocations
|
||||||
def g(count=10):
|
def g(count=10):
|
||||||
if count:
|
if count:
|
||||||
return g(count-1)
|
return g(count-1) + 1
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
with captured_output("stderr") as stderr_g:
|
with captured_output("stderr") as stderr_g:
|
||||||
|
@ -1715,13 +1892,13 @@ class TracebackFormatMixin:
|
||||||
lineno_g = g.__code__.co_firstlineno
|
lineno_g = g.__code__.co_firstlineno
|
||||||
result_g = (
|
result_g = (
|
||||||
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
||||||
' return g(count-1)\n'
|
' return g(count-1) + 1\n'
|
||||||
' ~^^^^^^^^^\n'
|
' ~^^^^^^^^^\n'
|
||||||
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
||||||
' return g(count-1)\n'
|
' return g(count-1) + 1\n'
|
||||||
' ~^^^^^^^^^\n'
|
' ~^^^^^^^^^\n'
|
||||||
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
||||||
' return g(count-1)\n'
|
' return g(count-1) + 1\n'
|
||||||
' ~^^^^^^^^^\n'
|
' ~^^^^^^^^^\n'
|
||||||
' [Previous line repeated 7 more times]\n'
|
' [Previous line repeated 7 more times]\n'
|
||||||
f' File "{__file__}", line {lineno_g+3}, in g\n'
|
f' File "{__file__}", line {lineno_g+3}, in g\n'
|
||||||
|
@ -1760,13 +1937,10 @@ class TracebackFormatMixin:
|
||||||
' ~^^\n'
|
' ~^^\n'
|
||||||
f' File "{__file__}", line {lineno_h+2}, in h\n'
|
f' File "{__file__}", line {lineno_h+2}, in h\n'
|
||||||
' return h(count-1)\n'
|
' return h(count-1)\n'
|
||||||
' ~^^^^^^^^^\n'
|
|
||||||
f' File "{__file__}", line {lineno_h+2}, in h\n'
|
f' File "{__file__}", line {lineno_h+2}, in h\n'
|
||||||
' return h(count-1)\n'
|
' return h(count-1)\n'
|
||||||
' ~^^^^^^^^^\n'
|
|
||||||
f' File "{__file__}", line {lineno_h+2}, in h\n'
|
f' File "{__file__}", line {lineno_h+2}, in h\n'
|
||||||
' return h(count-1)\n'
|
' return h(count-1)\n'
|
||||||
' ~^^^^^^^^^\n'
|
|
||||||
' [Previous line repeated 7 more times]\n'
|
' [Previous line repeated 7 more times]\n'
|
||||||
f' File "{__file__}", line {lineno_h+3}, in h\n'
|
f' File "{__file__}", line {lineno_h+3}, in h\n'
|
||||||
' g()\n'
|
' g()\n'
|
||||||
|
@ -1786,13 +1960,13 @@ class TracebackFormatMixin:
|
||||||
self.fail("no error raised")
|
self.fail("no error raised")
|
||||||
result_g = (
|
result_g = (
|
||||||
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
||||||
' return g(count-1)\n'
|
' return g(count-1) + 1\n'
|
||||||
' ~^^^^^^^^^\n'
|
' ~^^^^^^^^^\n'
|
||||||
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
||||||
' return g(count-1)\n'
|
' return g(count-1) + 1\n'
|
||||||
' ~^^^^^^^^^\n'
|
' ~^^^^^^^^^\n'
|
||||||
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
||||||
' return g(count-1)\n'
|
' return g(count-1) + 1\n'
|
||||||
' ~^^^^^^^^^\n'
|
' ~^^^^^^^^^\n'
|
||||||
f' File "{__file__}", line {lineno_g+3}, in g\n'
|
f' File "{__file__}", line {lineno_g+3}, in g\n'
|
||||||
' raise ValueError\n'
|
' raise ValueError\n'
|
||||||
|
@ -1800,7 +1974,7 @@ class TracebackFormatMixin:
|
||||||
)
|
)
|
||||||
tb_line = (
|
tb_line = (
|
||||||
'Traceback (most recent call last):\n'
|
'Traceback (most recent call last):\n'
|
||||||
f' File "{__file__}", line {lineno_g+80}, in _check_recursive_traceback_display\n'
|
f' File "{__file__}", line {lineno_g+77}, in _check_recursive_traceback_display\n'
|
||||||
' g(traceback._RECURSIVE_CUTOFF)\n'
|
' g(traceback._RECURSIVE_CUTOFF)\n'
|
||||||
' ~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n'
|
' ~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n'
|
||||||
)
|
)
|
||||||
|
@ -1818,13 +1992,13 @@ class TracebackFormatMixin:
|
||||||
self.fail("no error raised")
|
self.fail("no error raised")
|
||||||
result_g = (
|
result_g = (
|
||||||
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
||||||
' return g(count-1)\n'
|
' return g(count-1) + 1\n'
|
||||||
' ~^^^^^^^^^\n'
|
' ~^^^^^^^^^\n'
|
||||||
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
||||||
' return g(count-1)\n'
|
' return g(count-1) + 1\n'
|
||||||
' ~^^^^^^^^^\n'
|
' ~^^^^^^^^^\n'
|
||||||
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
f' File "{__file__}", line {lineno_g+2}, in g\n'
|
||||||
' return g(count-1)\n'
|
' return g(count-1) + 1\n'
|
||||||
' ~^^^^^^^^^\n'
|
' ~^^^^^^^^^\n'
|
||||||
' [Previous line repeated 1 more time]\n'
|
' [Previous line repeated 1 more time]\n'
|
||||||
f' File "{__file__}", line {lineno_g+3}, in g\n'
|
f' File "{__file__}", line {lineno_g+3}, in g\n'
|
||||||
|
@ -1833,7 +2007,7 @@ class TracebackFormatMixin:
|
||||||
)
|
)
|
||||||
tb_line = (
|
tb_line = (
|
||||||
'Traceback (most recent call last):\n'
|
'Traceback (most recent call last):\n'
|
||||||
f' File "{__file__}", line {lineno_g+112}, in _check_recursive_traceback_display\n'
|
f' File "{__file__}", line {lineno_g+109}, in _check_recursive_traceback_display\n'
|
||||||
' g(traceback._RECURSIVE_CUTOFF + 1)\n'
|
' g(traceback._RECURSIVE_CUTOFF + 1)\n'
|
||||||
' ~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n'
|
' ~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n'
|
||||||
)
|
)
|
||||||
|
@ -4287,11 +4461,14 @@ class TestColorizedTraceback(unittest.TestCase):
|
||||||
x = {'a':{'b': None}}
|
x = {'a':{'b': None}}
|
||||||
y = x['a']['b']['c']
|
y = x['a']['b']['c']
|
||||||
|
|
||||||
def baz(*args):
|
def baz2(*args):
|
||||||
return foo(1,2,3,4)
|
return (lambda *args: foo(*args))(1,2,3,4)
|
||||||
|
|
||||||
|
def baz1(*args):
|
||||||
|
return baz2(1,2,3,4)
|
||||||
|
|
||||||
def bar():
|
def bar():
|
||||||
return baz(1,
|
return baz1(1,
|
||||||
2,3
|
2,3
|
||||||
,4)
|
,4)
|
||||||
try:
|
try:
|
||||||
|
@ -4305,10 +4482,10 @@ class TestColorizedTraceback(unittest.TestCase):
|
||||||
boldr = traceback._ANSIColors.BOLD_RED
|
boldr = traceback._ANSIColors.BOLD_RED
|
||||||
reset = traceback._ANSIColors.RESET
|
reset = traceback._ANSIColors.RESET
|
||||||
self.assertIn("y = " + red + "x['a']['b']" + reset + boldr + "['c']" + reset, lines)
|
self.assertIn("y = " + red + "x['a']['b']" + reset + boldr + "['c']" + reset, lines)
|
||||||
self.assertIn("return " + red + "foo" + reset + boldr + "(1,2,3,4)" + reset, lines)
|
self.assertIn("return " + red + "(lambda *args: foo(*args))" + reset + boldr + "(1,2,3,4)" + reset, lines)
|
||||||
self.assertIn("return " + red + "baz" + reset + boldr + "(1," + reset, lines)
|
self.assertIn("return (lambda *args: " + red + "foo" + reset + boldr + "(*args)" + reset + ")(1,2,3,4)", lines)
|
||||||
self.assertIn(boldr + "2,3" + reset, lines)
|
self.assertIn("return baz2(1,2,3,4)", lines)
|
||||||
self.assertIn(boldr + ",4)" + reset, lines)
|
self.assertIn("return baz1(1,\n 2,3\n ,4)", lines)
|
||||||
self.assertIn(red + "bar" + reset + boldr + "()" + reset, lines)
|
self.assertIn(red + "bar" + reset + boldr + "()" + reset, lines)
|
||||||
|
|
||||||
def test_colorized_syntax_error(self):
|
def test_colorized_syntax_error(self):
|
||||||
|
|
|
@ -617,13 +617,10 @@ class StackSummary(list):
|
||||||
|
|
||||||
# attempt to parse for anchors
|
# attempt to parse for anchors
|
||||||
anchors = None
|
anchors = None
|
||||||
|
show_carets = False
|
||||||
with suppress(Exception):
|
with suppress(Exception):
|
||||||
anchors = _extract_caret_anchors_from_line_segment(segment)
|
anchors = _extract_caret_anchors_from_line_segment(segment)
|
||||||
|
show_carets = self.should_show_carets(start_offset, end_offset, all_lines, anchors)
|
||||||
# only use carets if there are anchors or the carets do not span all lines
|
|
||||||
show_carets = False
|
|
||||||
if anchors or all_lines[0][:start_offset].lstrip() or all_lines[-1][end_offset:].rstrip():
|
|
||||||
show_carets = True
|
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
|
@ -737,6 +734,37 @@ class StackSummary(list):
|
||||||
|
|
||||||
return ''.join(row)
|
return ''.join(row)
|
||||||
|
|
||||||
|
def should_show_carets(self, start_offset, end_offset, all_lines, anchors):
|
||||||
|
with suppress(SyntaxError, ImportError):
|
||||||
|
import ast
|
||||||
|
tree = ast.parse('\n'.join(all_lines))
|
||||||
|
statement = tree.body[0]
|
||||||
|
value = None
|
||||||
|
def _spawns_full_line(value):
|
||||||
|
return (
|
||||||
|
value.lineno == 1
|
||||||
|
and value.end_lineno == len(all_lines)
|
||||||
|
and value.col_offset == start_offset
|
||||||
|
and value.end_col_offset == end_offset
|
||||||
|
)
|
||||||
|
match statement:
|
||||||
|
case ast.Return(value=ast.Call()):
|
||||||
|
if isinstance(statement.value.func, ast.Name):
|
||||||
|
value = statement.value
|
||||||
|
case ast.Assign(value=ast.Call()):
|
||||||
|
if (
|
||||||
|
len(statement.targets) == 1 and
|
||||||
|
isinstance(statement.targets[0], ast.Name)
|
||||||
|
):
|
||||||
|
value = statement.value
|
||||||
|
if value is not None and _spawns_full_line(value):
|
||||||
|
return False
|
||||||
|
if anchors:
|
||||||
|
return True
|
||||||
|
if all_lines[0][:start_offset].lstrip() or all_lines[-1][end_offset:].rstrip():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def format(self, **kwargs):
|
def format(self, **kwargs):
|
||||||
"""Format the stack ready for printing.
|
"""Format the stack ready for printing.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Elide uninformative traceback indicators in ``return`` and simple
|
||||||
|
``assignment`` statements. Patch by Pablo Galindo.
|
Loading…
Add table
Add a link
Reference in a new issue