@@ -389,6 +389,7 @@ def bug42562():
389
389
POP_EXCEPT
390
390
RERAISE 1
391
391
ExceptionTable:
392
+ 4 rows
392
393
""" % (TRACEBACK_CODE .co_firstlineno ,
393
394
TRACEBACK_CODE .co_firstlineno + 1 ,
394
395
TRACEBACK_CODE .co_firstlineno + 2 ,
@@ -421,6 +422,133 @@ def _fstring(a, b, c, d):
421
422
RETURN_VALUE
422
423
""" % (_fstring .__code__ .co_firstlineno , _fstring .__code__ .co_firstlineno + 1 )
423
424
425
+ def _with (c ):
426
+ with c :
427
+ x = 1
428
+ y = 2
429
+
430
+ dis_with = """\
431
+ %3d RESUME 0
432
+
433
+ %3d LOAD_FAST 0 (c)
434
+ BEFORE_WITH
435
+ POP_TOP
436
+
437
+ %3d LOAD_CONST 1 (1)
438
+ STORE_FAST 1 (x)
439
+
440
+ %3d LOAD_CONST 0 (None)
441
+ LOAD_CONST 0 (None)
442
+ LOAD_CONST 0 (None)
443
+ CALL 2
444
+ POP_TOP
445
+
446
+ %3d LOAD_CONST 2 (2)
447
+ STORE_FAST 2 (y)
448
+ LOAD_CONST 0 (None)
449
+ RETURN_VALUE
450
+
451
+ %3d >> PUSH_EXC_INFO
452
+ WITH_EXCEPT_START
453
+ POP_JUMP_FORWARD_IF_TRUE 1 (to 46)
454
+ RERAISE 2
455
+ >> POP_TOP
456
+ POP_EXCEPT
457
+ POP_TOP
458
+ POP_TOP
459
+
460
+ %3d LOAD_CONST 2 (2)
461
+ STORE_FAST 2 (y)
462
+ LOAD_CONST 0 (None)
463
+ RETURN_VALUE
464
+ >> COPY 3
465
+ POP_EXCEPT
466
+ RERAISE 1
467
+ ExceptionTable:
468
+ 2 rows
469
+ """ % (_with .__code__ .co_firstlineno ,
470
+ _with .__code__ .co_firstlineno + 1 ,
471
+ _with .__code__ .co_firstlineno + 2 ,
472
+ _with .__code__ .co_firstlineno + 1 ,
473
+ _with .__code__ .co_firstlineno + 3 ,
474
+ _with .__code__ .co_firstlineno + 1 ,
475
+ _with .__code__ .co_firstlineno + 3 ,
476
+ )
477
+
478
+ async def _asyncwith (c ):
479
+ async with c :
480
+ x = 1
481
+ y = 2
482
+
483
+ dis_asyncwith = """\
484
+ %3d RETURN_GENERATOR
485
+ POP_TOP
486
+ RESUME 0
487
+
488
+ %3d LOAD_FAST 0 (c)
489
+ BEFORE_ASYNC_WITH
490
+ GET_AWAITABLE 1
491
+ LOAD_CONST 0 (None)
492
+ >> SEND 3 (to 22)
493
+ YIELD_VALUE 3
494
+ RESUME 3
495
+ JUMP_BACKWARD_NO_INTERRUPT 4 (to 14)
496
+ >> POP_TOP
497
+
498
+ %3d LOAD_CONST 1 (1)
499
+ STORE_FAST 1 (x)
500
+
501
+ %3d LOAD_CONST 0 (None)
502
+ LOAD_CONST 0 (None)
503
+ LOAD_CONST 0 (None)
504
+ CALL 2
505
+ GET_AWAITABLE 2
506
+ LOAD_CONST 0 (None)
507
+ >> SEND 3 (to 56)
508
+ YIELD_VALUE 2
509
+ RESUME 3
510
+ JUMP_BACKWARD_NO_INTERRUPT 4 (to 48)
511
+ >> POP_TOP
512
+
513
+ %3d LOAD_CONST 2 (2)
514
+ STORE_FAST 2 (y)
515
+ LOAD_CONST 0 (None)
516
+ RETURN_VALUE
517
+
518
+ %3d >> PUSH_EXC_INFO
519
+ WITH_EXCEPT_START
520
+ GET_AWAITABLE 2
521
+ LOAD_CONST 0 (None)
522
+ >> SEND 3 (to 82)
523
+ YIELD_VALUE 6
524
+ RESUME 3
525
+ JUMP_BACKWARD_NO_INTERRUPT 4 (to 74)
526
+ >> POP_JUMP_FORWARD_IF_TRUE 1 (to 86)
527
+ RERAISE 2
528
+ >> POP_TOP
529
+ POP_EXCEPT
530
+ POP_TOP
531
+ POP_TOP
532
+
533
+ %3d LOAD_CONST 2 (2)
534
+ STORE_FAST 2 (y)
535
+ LOAD_CONST 0 (None)
536
+ RETURN_VALUE
537
+ >> COPY 3
538
+ POP_EXCEPT
539
+ RERAISE 1
540
+ ExceptionTable:
541
+ 2 rows
542
+ """ % (_asyncwith .__code__ .co_firstlineno ,
543
+ _asyncwith .__code__ .co_firstlineno + 1 ,
544
+ _asyncwith .__code__ .co_firstlineno + 2 ,
545
+ _asyncwith .__code__ .co_firstlineno + 1 ,
546
+ _asyncwith .__code__ .co_firstlineno + 3 ,
547
+ _asyncwith .__code__ .co_firstlineno + 1 ,
548
+ _asyncwith .__code__ .co_firstlineno + 3 ,
549
+ )
550
+
551
+
424
552
def _tryfinally (a , b ):
425
553
try :
426
554
return a
@@ -455,6 +583,7 @@ def _tryfinallyconst(b):
455
583
POP_EXCEPT
456
584
RERAISE 1
457
585
ExceptionTable:
586
+ 2 rows
458
587
""" % (_tryfinally .__code__ .co_firstlineno ,
459
588
_tryfinally .__code__ .co_firstlineno + 1 ,
460
589
_tryfinally .__code__ .co_firstlineno + 2 ,
@@ -484,6 +613,7 @@ def _tryfinallyconst(b):
484
613
POP_EXCEPT
485
614
RERAISE 1
486
615
ExceptionTable:
616
+ 1 row
487
617
""" % (_tryfinallyconst .__code__ .co_firstlineno ,
488
618
_tryfinallyconst .__code__ .co_firstlineno + 1 ,
489
619
_tryfinallyconst .__code__ .co_firstlineno + 2 ,
@@ -678,6 +808,18 @@ def assert_offsets_increasing(self, text, delta):
678
808
self .assertGreaterEqual (offset , expected_offset , line )
679
809
expected_offset = offset + delta
680
810
811
+ def assert_exception_table_increasing (self , lines ):
812
+ prev_start , prev_end = - 1 , - 1
813
+ count = 0
814
+ for line in lines :
815
+ m = re .match (r' (\d+) to (\d+) -> \d+ \[\d+\]' , line )
816
+ start , end = [int (g ) for g in m .groups ()]
817
+ self .assertGreaterEqual (end , start )
818
+ self .assertGreater (start , prev_end )
819
+ prev_start , prev_end = start , end
820
+ count += 1
821
+ return count
822
+
681
823
def strip_offsets (self , text ):
682
824
lines = text .splitlines (True )
683
825
start , end = self .find_offset_column (lines )
@@ -691,6 +833,9 @@ def strip_offsets(self, text):
691
833
res .append (line )
692
834
else :
693
835
res .append (line [:start ] + line [end :])
836
+ num_rows = self .assert_exception_table_increasing (lines )
837
+ if num_rows :
838
+ res .append (f"{ num_rows } row{ 's' if num_rows > 1 else '' } \n " )
694
839
return "" .join (res )
695
840
696
841
def do_disassembly_compare (self , got , expected , with_offsets = False ):
@@ -883,6 +1028,12 @@ def test_disassemble_coroutine(self):
883
1028
def test_disassemble_fstring (self ):
884
1029
self .do_disassembly_test (_fstring , dis_fstring )
885
1030
1031
+ def test_disassemble_with (self ):
1032
+ self .do_disassembly_test (_with , dis_with )
1033
+
1034
+ def test_disassemble_asyncwith (self ):
1035
+ self .do_disassembly_test (_asyncwith , dis_asyncwith )
1036
+
886
1037
def test_disassemble_try_finally (self ):
887
1038
self .do_disassembly_test (_tryfinally , dis_tryfinally )
888
1039
self .do_disassembly_test (_tryfinallyconst , dis_tryfinallyconst )
@@ -1471,16 +1622,16 @@ def _prepare_test_cases():
1471
1622
Instruction (opname = 'RETURN_VALUE' , opcode = 83 , arg = None , argval = None , argrepr = '' , offset = 302 , starts_line = None , is_jump_target = False , positions = None ),
1472
1623
Instruction (opname = 'PUSH_EXC_INFO' , opcode = 35 , arg = None , argval = None , argrepr = '' , offset = 304 , starts_line = 25 , is_jump_target = False , positions = None ),
1473
1624
Instruction (opname = 'WITH_EXCEPT_START' , opcode = 49 , arg = None , argval = None , argrepr = '' , offset = 306 , starts_line = None , is_jump_target = False , positions = None ),
1474
- Instruction (opname = 'POP_JUMP_FORWARD_IF_TRUE' , opcode = 115 , arg = 4 , argval = 318 , argrepr = 'to 318 ' , offset = 308 , starts_line = None , is_jump_target = False , positions = None ),
1625
+ Instruction (opname = 'POP_JUMP_FORWARD_IF_TRUE' , opcode = 115 , arg = 1 , argval = 312 , argrepr = 'to 312 ' , offset = 308 , starts_line = None , is_jump_target = False , positions = None ),
1475
1626
Instruction (opname = 'RERAISE' , opcode = 119 , arg = 2 , argval = 2 , argrepr = '' , offset = 310 , starts_line = None , is_jump_target = False , positions = None ),
1476
- Instruction (opname = 'COPY ' , opcode = 120 , arg = 3 , argval = 3 , argrepr = '' , offset = 312 , starts_line = None , is_jump_target = False , positions = None ),
1627
+ Instruction (opname = 'POP_TOP ' , opcode = 1 , arg = None , argval = None , argrepr = '' , offset = 312 , starts_line = None , is_jump_target = True , positions = None ),
1477
1628
Instruction (opname = 'POP_EXCEPT' , opcode = 89 , arg = None , argval = None , argrepr = '' , offset = 314 , starts_line = None , is_jump_target = False , positions = None ),
1478
- Instruction (opname = 'RERAISE ' , opcode = 119 , arg = 1 , argval = 1 , argrepr = '' , offset = 316 , starts_line = None , is_jump_target = False , positions = None ),
1479
- Instruction (opname = 'POP_TOP' , opcode = 1 , arg = None , argval = None , argrepr = '' , offset = 318 , starts_line = None , is_jump_target = True , positions = None ),
1480
- Instruction (opname = 'POP_EXCEPT ' , opcode = 89 , arg = None , argval = None , argrepr = '' , offset = 320 , starts_line = None , is_jump_target = False , positions = None ),
1481
- Instruction (opname = 'POP_TOP ' , opcode = 1 , arg = None , argval = None , argrepr = '' , offset = 322 , starts_line = None , is_jump_target = False , positions = None ),
1482
- Instruction (opname = 'POP_TOP ' , opcode = 1 , arg = None , argval = None , argrepr = '' , offset = 324 , starts_line = None , is_jump_target = False , positions = None ),
1483
- Instruction (opname = 'JUMP_BACKWARD ' , opcode = 140 , arg = 27 , argval = 274 , argrepr = 'to 274 ' , offset = 326 , starts_line = None , is_jump_target = False , positions = None ),
1629
+ Instruction (opname = 'POP_TOP ' , opcode = 1 , arg = None , argval = None , argrepr = '' , offset = 316 , starts_line = None , is_jump_target = False , positions = None ),
1630
+ Instruction (opname = 'POP_TOP' , opcode = 1 , arg = None , argval = None , argrepr = '' , offset = 318 , starts_line = None , is_jump_target = False , positions = None ),
1631
+ Instruction (opname = 'JUMP_BACKWARD ' , opcode = 140 , arg = 24 , argval = 274 , argrepr = 'to 274 ' , offset = 320 , starts_line = None , is_jump_target = False , positions = None ),
1632
+ Instruction (opname = 'COPY ' , opcode = 120 , arg = 3 , argval = 3 , argrepr = '' , offset = 322 , starts_line = None , is_jump_target = False , positions = None ),
1633
+ Instruction (opname = 'POP_EXCEPT ' , opcode = 89 , arg = None , argval = None , argrepr = '' , offset = 324 , starts_line = None , is_jump_target = False , positions = None ),
1634
+ Instruction (opname = 'RERAISE ' , opcode = 119 , arg = 1 , argval = 1 , argrepr = '' , offset = 326 , starts_line = None , is_jump_target = False , positions = None ),
1484
1635
Instruction (opname = 'PUSH_EXC_INFO' , opcode = 35 , arg = None , argval = None , argrepr = '' , offset = 328 , starts_line = None , is_jump_target = False , positions = None ),
1485
1636
Instruction (opname = 'LOAD_GLOBAL' , opcode = 116 , arg = 4 , argval = 'ZeroDivisionError' , argrepr = 'ZeroDivisionError' , offset = 330 , starts_line = 22 , is_jump_target = False , positions = None ),
1486
1637
Instruction (opname = 'CHECK_EXC_MATCH' , opcode = 36 , arg = None , argval = None , argrepr = '' , offset = 342 , starts_line = None , is_jump_target = False , positions = None ),
0 commit comments