@@ -102,6 +102,7 @@ def _step_logger():
102
102
103
103
@dataclasses .dataclass
104
104
class BlockStackEntry :
105
+ id : int
105
106
target : Instruction
106
107
stack_index : Optional [int ] = None
107
108
with_context : ContextWrappingVariable = None
@@ -878,11 +879,11 @@ def jump(self, inst):
878
879
879
880
def SETUP_LOOP (self , inst ):
880
881
# only exists in python<=3.7
881
- self .block_stack .append (BlockStackEntry (inst .target ))
882
+ self .block_stack .append (BlockStackEntry (0 , inst .target ))
882
883
883
884
def SETUP_EXCEPT (self , inst ):
884
885
# only exists in python<=3.7
885
- self .block_stack .append (BlockStackEntry (inst .target ))
886
+ self .block_stack .append (BlockStackEntry (0 , inst .target ))
886
887
887
888
def POP_BLOCK (self , inst ):
888
889
self .block_stack .pop ()
@@ -894,10 +895,12 @@ def SETUP_WITH(self, inst):
894
895
self .output .guards .update (ctx .guards )
895
896
896
897
if isinstance (self , InstructionTranslator ):
897
- self .block_stack .append (BlockStackEntry (inst .target , len (self .stack ), ctx ))
898
+ self .block_stack .append (
899
+ BlockStackEntry (0 , inst .target , len (self .stack ), ctx )
900
+ )
898
901
else :
899
902
# can't restore this while inlining
900
- self .block_stack .append (BlockStackEntry (inst .target ))
903
+ self .block_stack .append (BlockStackEntry (0 , inst .target ))
901
904
self .push (
902
905
WithExitFunctionVariable (
903
906
ctx ,
@@ -908,7 +911,7 @@ def SETUP_WITH(self, inst):
908
911
self .push (ctx .enter (self ))
909
912
910
913
def SETUP_FINALLY (self , inst ):
911
- self .block_stack .append (BlockStackEntry (inst .target ))
914
+ self .block_stack .append (BlockStackEntry (0 , inst .target ))
912
915
913
916
def BEGIN_FINALLY (self , inst ):
914
917
self .push (None )
@@ -1569,6 +1572,13 @@ def CALL(self, inst):
1569
1572
kwargs = {}
1570
1573
self .call_function (fn , args , kwargs )
1571
1574
self .kw_names = None
1575
+ # 3.11 removed POP_BLOCK, so we manually pop the block stack here
1576
+ if (
1577
+ isinstance (fn , WithExitFunctionVariable )
1578
+ and len (self .block_stack ) > 0
1579
+ and id (fn ) == self .block_stack [- 1 ].id
1580
+ ):
1581
+ self .block_stack .pop ()
1572
1582
1573
1583
def COPY (self , inst ):
1574
1584
self .push (self .stack [- inst .arg ])
@@ -1592,6 +1602,30 @@ def SWAP(self, inst):
1592
1602
def CACHE (self , inst ):
1593
1603
pass
1594
1604
1605
+ def BEFORE_WITH (self , inst ):
1606
+ ctx = self .pop ()
1607
+ if not isinstance (ctx , ContextWrappingVariable ):
1608
+ unimplemented (f"BEFORE_WITH { ctx } " )
1609
+ self .output .guards .update (ctx .guards )
1610
+
1611
+ exit = WithExitFunctionVariable (
1612
+ ctx ,
1613
+ inst .target ,
1614
+ ** VariableTracker .propagate (ctx ),
1615
+ )
1616
+ # 3.11 no longer uses a block stack, but we still keep track of one
1617
+ # so that we know which contexts are currently active.
1618
+ if isinstance (self , InstructionTranslator ):
1619
+ self .block_stack .append (
1620
+ BlockStackEntry (id (exit ), inst .target , self .real_stack_len (), ctx )
1621
+ )
1622
+ else :
1623
+ # can't restore this while inlining
1624
+ self .block_stack .append (BlockStackEntry (id (exit ), inst .target ))
1625
+
1626
+ self .push (exit )
1627
+ self .push (ctx .enter (self ))
1628
+
1595
1629
def copy_graphstate (self ) -> InstructionTranslatorGraphState :
1596
1630
"""Create a checkpoint of the current state by copying everything"""
1597
1631
return InstructionTranslatorGraphState (
0 commit comments