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

``