bpo-34588: Fix an off-by-one error in traceback formatting. (GH-9077) · python/cpython@afb25bc (original) (raw)
`@@ -373,7 +373,7 @@ def g(count=10):
`
373
373
`' return g(count-1)\n'
`
374
374
`f' File "{file}", line {lineno_g+2}, in g\n'
`
375
375
`' return g(count-1)\n'
`
376
``
`-
' [Previous line repeated 6 more times]\n'
`
``
376
`+
' [Previous line repeated 7 more times]\n'
`
377
377
`f' File "{file}", line {lineno_g+3}, in g\n'
`
378
378
`' raise ValueError\n'
`
379
379
`'ValueError\n'
`
`@@ -412,14 +412,71 @@ def h(count=10):
`
412
412
`' return h(count-1)\n'
`
413
413
`f' File "{file}", line {lineno_h+2}, in h\n'
`
414
414
`' return h(count-1)\n'
`
415
``
`-
' [Previous line repeated 6 more times]\n'
`
``
415
`+
' [Previous line repeated 7 more times]\n'
`
416
416
`f' File "{file}", line {lineno_h+3}, in h\n'
`
417
417
`' g()\n'
`
418
418
` )
`
419
419
`expected = (result_h + result_g).splitlines()
`
420
420
`actual = stderr_h.getvalue().splitlines()
`
421
421
`self.assertEqual(actual, expected)
`
422
422
``
``
423
`+
Check the boundary conditions. First, test just below the cutoff.
`
``
424
`+
with captured_output("stderr") as stderr_g:
`
``
425
`+
try:
`
``
426
`+
g(traceback._RECURSIVE_CUTOFF)
`
``
427
`+
except ValueError as exc:
`
``
428
`+
render_exc()
`
``
429
`+
else:
`
``
430
`+
self.fail("no error raised")
`
``
431
`+
result_g = (
`
``
432
`+
f' File "{file}", line {lineno_g+2}, in g\n'
`
``
433
`+
' return g(count-1)\n'
`
``
434
`+
f' File "{file}", line {lineno_g+2}, in g\n'
`
``
435
`+
' return g(count-1)\n'
`
``
436
`+
f' File "{file}", line {lineno_g+2}, in g\n'
`
``
437
`+
' return g(count-1)\n'
`
``
438
`+
f' File "{file}", line {lineno_g+3}, in g\n'
`
``
439
`+
' raise ValueError\n'
`
``
440
`+
'ValueError\n'
`
``
441
`+
)
`
``
442
`+
tb_line = (
`
``
443
`+
'Traceback (most recent call last):\n'
`
``
444
`+
f' File "{file}", line {lineno_g+71}, in _check_recursive_traceback_display\n'
`
``
445
`+
' g(traceback._RECURSIVE_CUTOFF)\n'
`
``
446
`+
)
`
``
447
`+
expected = (tb_line + result_g).splitlines()
`
``
448
`+
actual = stderr_g.getvalue().splitlines()
`
``
449
`+
self.assertEqual(actual, expected)
`
``
450
+
``
451
`+
Second, test just above the cutoff.
`
``
452
`+
with captured_output("stderr") as stderr_g:
`
``
453
`+
try:
`
``
454
`+
g(traceback._RECURSIVE_CUTOFF + 1)
`
``
455
`+
except ValueError as exc:
`
``
456
`+
render_exc()
`
``
457
`+
else:
`
``
458
`+
self.fail("no error raised")
`
``
459
`+
result_g = (
`
``
460
`+
f' File "{file}", line {lineno_g+2}, in g\n'
`
``
461
`+
' return g(count-1)\n'
`
``
462
`+
f' File "{file}", line {lineno_g+2}, in g\n'
`
``
463
`+
' return g(count-1)\n'
`
``
464
`+
f' File "{file}", line {lineno_g+2}, in g\n'
`
``
465
`+
' return g(count-1)\n'
`
``
466
`+
' [Previous line repeated 1 more time]\n'
`
``
467
`+
f' File "{file}", line {lineno_g+3}, in g\n'
`
``
468
`+
' raise ValueError\n'
`
``
469
`+
'ValueError\n'
`
``
470
`+
)
`
``
471
`+
tb_line = (
`
``
472
`+
'Traceback (most recent call last):\n'
`
``
473
`+
f' File "{file}", line {lineno_g+99}, in _check_recursive_traceback_display\n'
`
``
474
`+
' g(traceback._RECURSIVE_CUTOFF + 1)\n'
`
``
475
`+
)
`
``
476
`+
expected = (tb_line + result_g).splitlines()
`
``
477
`+
actual = stderr_g.getvalue().splitlines()
`
``
478
`+
self.assertEqual(actual, expected)
`
``
479
+
423
480
`def test_recursive_traceback_python(self):
`
424
481
`self._check_recursive_traceback_display(traceback.print_exc)
`
425
482
``