16
16
17
17
18
18
test_code = namedtuple ('code' , ['co_filename' , 'co_name' ])
19
+ test_code .co_positions = lambda _ : iter ([(6 , 6 , 0 , 0 )])
19
20
test_frame = namedtuple ('frame' , ['f_code' , 'f_globals' , 'f_locals' ])
20
- test_tb = namedtuple ('tb' , ['tb_frame' , 'tb_lineno' , 'tb_next' ])
21
+ test_tb = namedtuple ('tb' , ['tb_frame' , 'tb_lineno' , 'tb_next' , 'tb_lasti' ])
21
22
22
23
23
24
class TracebackCases (unittest .TestCase ):
@@ -153,9 +154,9 @@ def do_test(firstlines, message, charset, lineno):
153
154
self .assertTrue (stdout [2 ].endswith (err_line ),
154
155
"Invalid traceback line: {0!r} instead of {1!r}" .format (
155
156
stdout [2 ], err_line ))
156
- self .assertTrue (stdout [3 ] == err_msg ,
157
+ self .assertTrue (stdout [4 ] == err_msg ,
157
158
"Invalid error message: {0!r} instead of {1!r}" .format (
158
- stdout [3 ], err_msg ))
159
+ stdout [4 ], err_msg ))
159
160
160
161
do_test ("" , "foo" , "ascii" , 3 )
161
162
for charset in ("ascii" , "iso-8859-1" , "utf-8" , "GBK" ):
@@ -299,9 +300,9 @@ def check_traceback_format(self, cleanup_func=None):
299
300
300
301
# Make sure that the traceback is properly indented.
301
302
tb_lines = python_fmt .splitlines ()
302
- self .assertEqual (len (tb_lines ), 5 )
303
+ self .assertEqual (len (tb_lines ), 7 )
303
304
banner = tb_lines [0 ]
304
- location , source_line = tb_lines [- 2 : ]
305
+ location , source_line = tb_lines [- 3 ], tb_lines [ - 2 ]
305
306
self .assertTrue (banner .startswith ('Traceback' ))
306
307
self .assertTrue (location .startswith (' File' ))
307
308
self .assertTrue (source_line .startswith (' raise' ))
@@ -365,12 +366,16 @@ def f():
365
366
'Traceback (most recent call last):\n '
366
367
f' File "{ __file__ } ", line { lineno_f + 5 } , in _check_recursive_traceback_display\n '
367
368
' f()\n '
369
+ ' ^^^\n '
368
370
f' File "{ __file__ } ", line { lineno_f + 1 } , in f\n '
369
371
' f()\n '
372
+ ' ^^^\n '
370
373
f' File "{ __file__ } ", line { lineno_f + 1 } , in f\n '
371
374
' f()\n '
375
+ ' ^^^\n '
372
376
f' File "{ __file__ } ", line { lineno_f + 1 } , in f\n '
373
377
' f()\n '
378
+ ' ^^^\n '
374
379
# XXX: The following line changes depending on whether the tests
375
380
# are run through the interactive interpreter or with -m
376
381
# It also varies depending on the platform (stack size)
@@ -411,19 +416,24 @@ def g(count=10):
411
416
result_g = (
412
417
f' File "{ __file__ } ", line { lineno_g + 2 } , in g\n '
413
418
' return g(count-1)\n '
419
+ ' ^^^^^^^^^^\n '
414
420
f' File "{ __file__ } ", line { lineno_g + 2 } , in g\n '
415
421
' return g(count-1)\n '
422
+ ' ^^^^^^^^^^\n '
416
423
f' File "{ __file__ } ", line { lineno_g + 2 } , in g\n '
417
424
' return g(count-1)\n '
425
+ ' ^^^^^^^^^^\n '
418
426
' [Previous line repeated 7 more times]\n '
419
427
f' File "{ __file__ } ", line { lineno_g + 3 } , in g\n '
420
428
' raise ValueError\n '
429
+ ' ^^^^^^^^^^^^^^^^\n '
421
430
'ValueError\n '
422
431
)
423
432
tb_line = (
424
433
'Traceback (most recent call last):\n '
425
434
f' File "{ __file__ } ", line { lineno_g + 7 } , in _check_recursive_traceback_display\n '
426
435
' g()\n '
436
+ ' ^^^\n '
427
437
)
428
438
expected = (tb_line + result_g ).splitlines ()
429
439
actual = stderr_g .getvalue ().splitlines ()
@@ -448,15 +458,20 @@ def h(count=10):
448
458
'Traceback (most recent call last):\n '
449
459
f' File "{ __file__ } ", line { lineno_h + 7 } , in _check_recursive_traceback_display\n '
450
460
' h()\n '
461
+ ' ^^^\n '
451
462
f' File "{ __file__ } ", line { lineno_h + 2 } , in h\n '
452
463
' return h(count-1)\n '
464
+ ' ^^^^^^^^^^\n '
453
465
f' File "{ __file__ } ", line { lineno_h + 2 } , in h\n '
454
466
' return h(count-1)\n '
467
+ ' ^^^^^^^^^^\n '
455
468
f' File "{ __file__ } ", line { lineno_h + 2 } , in h\n '
456
469
' return h(count-1)\n '
470
+ ' ^^^^^^^^^^\n '
457
471
' [Previous line repeated 7 more times]\n '
458
472
f' File "{ __file__ } ", line { lineno_h + 3 } , in h\n '
459
473
' g()\n '
474
+ ' ^^^\n '
460
475
)
461
476
expected = (result_h + result_g ).splitlines ()
462
477
actual = stderr_h .getvalue ().splitlines ()
@@ -473,18 +488,23 @@ def h(count=10):
473
488
result_g = (
474
489
f' File "{ __file__ } ", line { lineno_g + 2 } , in g\n '
475
490
' return g(count-1)\n '
491
+ ' ^^^^^^^^^^\n '
476
492
f' File "{ __file__ } ", line { lineno_g + 2 } , in g\n '
477
493
' return g(count-1)\n '
494
+ ' ^^^^^^^^^^\n '
478
495
f' File "{ __file__ } ", line { lineno_g + 2 } , in g\n '
479
496
' return g(count-1)\n '
497
+ ' ^^^^^^^^^^\n '
480
498
f' File "{ __file__ } ", line { lineno_g + 3 } , in g\n '
481
499
' raise ValueError\n '
500
+ ' ^^^^^^^^^^^^^^^^\n '
482
501
'ValueError\n '
483
502
)
484
503
tb_line = (
485
504
'Traceback (most recent call last):\n '
486
- f' File "{ __file__ } ", line { lineno_g + 71 } , in _check_recursive_traceback_display\n '
505
+ f' File "{ __file__ } ", line { lineno_g + 81 } , in _check_recursive_traceback_display\n '
487
506
' g(traceback._RECURSIVE_CUTOFF)\n '
507
+ ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n '
488
508
)
489
509
expected = (tb_line + result_g ).splitlines ()
490
510
actual = stderr_g .getvalue ().splitlines ()
@@ -501,19 +521,24 @@ def h(count=10):
501
521
result_g = (
502
522
f' File "{ __file__ } ", line { lineno_g + 2 } , in g\n '
503
523
' return g(count-1)\n '
524
+ ' ^^^^^^^^^^\n '
504
525
f' File "{ __file__ } ", line { lineno_g + 2 } , in g\n '
505
526
' return g(count-1)\n '
527
+ ' ^^^^^^^^^^\n '
506
528
f' File "{ __file__ } ", line { lineno_g + 2 } , in g\n '
507
529
' return g(count-1)\n '
530
+ ' ^^^^^^^^^^\n '
508
531
' [Previous line repeated 1 more time]\n '
509
532
f' File "{ __file__ } ", line { lineno_g + 3 } , in g\n '
510
533
' raise ValueError\n '
534
+ ' ^^^^^^^^^^^^^^^^\n '
511
535
'ValueError\n '
512
536
)
513
537
tb_line = (
514
538
'Traceback (most recent call last):\n '
515
- f' File "{ __file__ } ", line { lineno_g + 99 } , in _check_recursive_traceback_display\n '
539
+ f' File "{ __file__ } ", line { lineno_g + 114 } , in _check_recursive_traceback_display\n '
516
540
' g(traceback._RECURSIVE_CUTOFF + 1)\n '
541
+ ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n '
517
542
)
518
543
expected = (tb_line + result_g ).splitlines ()
519
544
actual = stderr_g .getvalue ().splitlines ()
@@ -564,10 +589,10 @@ def __eq__(self, other):
564
589
exception_print (exc_val )
565
590
566
591
tb = stderr_f .getvalue ().strip ().splitlines ()
567
- self .assertEqual (11 , len (tb ))
568
- self .assertEqual (context_message .strip (), tb [5 ])
569
- self .assertIn ('UnhashableException: ex2' , tb [3 ])
570
- self .assertIn ('UnhashableException: ex1' , tb [10 ])
592
+ self .assertEqual (13 , len (tb ))
593
+ self .assertEqual (context_message .strip (), tb [6 ])
594
+ self .assertIn ('UnhashableException: ex2' , tb [4 ])
595
+ self .assertIn ('UnhashableException: ex1' , tb [12 ])
571
596
572
597
573
598
cause_message = (
@@ -597,8 +622,8 @@ def zero_div(self):
597
622
598
623
def check_zero_div (self , msg ):
599
624
lines = msg .splitlines ()
600
- self .assertTrue (lines [- 3 ].startswith (' File' ))
601
- self .assertIn ('1/0 # In zero_div' , lines [- 2 ])
625
+ self .assertTrue (lines [- 4 ].startswith (' File' ))
626
+ self .assertIn ('1/0 # In zero_div' , lines [- 3 ])
602
627
self .assertTrue (lines [- 1 ].startswith ('ZeroDivisionError' ), lines [- 1 ])
603
628
604
629
def test_simple (self ):
@@ -607,11 +632,11 @@ def test_simple(self):
607
632
except ZeroDivisionError as _ :
608
633
e = _
609
634
lines = self .get_report (e ).splitlines ()
610
- self .assertEqual (len (lines ), 4 )
635
+ self .assertEqual (len (lines ), 5 )
611
636
self .assertTrue (lines [0 ].startswith ('Traceback' ))
612
637
self .assertTrue (lines [1 ].startswith (' File' ))
613
638
self .assertIn ('1/0 # Marker' , lines [2 ])
614
- self .assertTrue (lines [3 ].startswith ('ZeroDivisionError' ))
639
+ self .assertTrue (lines [4 ].startswith ('ZeroDivisionError' ))
615
640
616
641
def test_cause (self ):
617
642
def inner_raise ():
@@ -650,11 +675,11 @@ def test_context_suppression(self):
650
675
except ZeroDivisionError as _ :
651
676
e = _
652
677
lines = self .get_report (e ).splitlines ()
653
- self .assertEqual (len (lines ), 4 )
678
+ self .assertEqual (len (lines ), 5 )
654
679
self .assertTrue (lines [0 ].startswith ('Traceback' ))
655
680
self .assertTrue (lines [1 ].startswith (' File' ))
656
681
self .assertIn ('ZeroDivisionError from None' , lines [2 ])
657
- self .assertTrue (lines [3 ].startswith ('ZeroDivisionError' ))
682
+ self .assertTrue (lines [4 ].startswith ('ZeroDivisionError' ))
658
683
659
684
def test_cause_and_context (self ):
660
685
# When both a cause and a context are set, only the cause should be
@@ -1346,7 +1371,7 @@ def test_lookup_lines(self):
1346
1371
e = Exception ("uh oh" )
1347
1372
c = test_code ('/foo.py' , 'method' )
1348
1373
f = test_frame (c , None , None )
1349
- tb = test_tb (f , 6 , None )
1374
+ tb = test_tb (f , 6 , None , 0 )
1350
1375
exc = traceback .TracebackException (Exception , e , tb , lookup_lines = False )
1351
1376
self .assertEqual (linecache .cache , {})
1352
1377
linecache .updatecache ('/foo.py' , globals ())
@@ -1357,7 +1382,7 @@ def test_locals(self):
1357
1382
e = Exception ("uh oh" )
1358
1383
c = test_code ('/foo.py' , 'method' )
1359
1384
f = test_frame (c , globals (), {'something' : 1 , 'other' : 'string' })
1360
- tb = test_tb (f , 6 , None )
1385
+ tb = test_tb (f , 6 , None , 0 )
1361
1386
exc = traceback .TracebackException (
1362
1387
Exception , e , tb , capture_locals = True )
1363
1388
self .assertEqual (
@@ -1368,7 +1393,7 @@ def test_no_locals(self):
1368
1393
e = Exception ("uh oh" )
1369
1394
c = test_code ('/foo.py' , 'method' )
1370
1395
f = test_frame (c , globals (), {'something' : 1 })
1371
- tb = test_tb (f , 6 , None )
1396
+ tb = test_tb (f , 6 , None , 0 )
1372
1397
exc = traceback .TracebackException (Exception , e , tb )
1373
1398
self .assertEqual (exc .stack [0 ].locals , None )
1374
1399
0 commit comments