@@ -524,7 +524,7 @@ def test_lines_loop(self):
524
524
sys .monitoring .set_events (TEST_TOOL , 0 )
525
525
sys .monitoring .register_callback (TEST_TOOL , E .LINE , None )
526
526
start = LineMonitoringTest .test_lines_loop .__code__ .co_firstlineno
527
- self .assertEqual (events , [start + 7 , 21 , 22 , 22 , 21 , start + 8 ])
527
+ self .assertEqual (events , [start + 7 , 21 , 22 , 21 , 22 , 21 , start + 8 ])
528
528
finally :
529
529
sys .monitoring .set_events (TEST_TOOL , 0 )
530
530
sys .monitoring .register_callback (TEST_TOOL , E .LINE , None )
@@ -1050,6 +1050,8 @@ def func3():
1050
1050
def line_from_offset (code , offset ):
1051
1051
for start , end , line in code .co_lines ():
1052
1052
if start <= offset < end :
1053
+ if line is None :
1054
+ return f"[offset={ offset } ]"
1053
1055
return line - code .co_firstlineno
1054
1056
return - 1
1055
1057
@@ -1072,9 +1074,20 @@ class BranchRecorder(JumpRecorder):
1072
1074
event_type = E .BRANCH
1073
1075
name = "branch"
1074
1076
1077
+ class ReturnRecorder :
1078
+
1079
+ event_type = E .PY_RETURN
1080
+
1081
+ def __init__ (self , events ):
1082
+ self .events = events
1083
+
1084
+ def __call__ (self , code , offset , val ):
1085
+ self .events .append (("return" , val ))
1086
+
1075
1087
1076
1088
JUMP_AND_BRANCH_RECORDERS = JumpRecorder , BranchRecorder
1077
1089
JUMP_BRANCH_AND_LINE_RECORDERS = JumpRecorder , BranchRecorder , LineRecorder
1090
+ FLOW_AND_LINE_RECORDERS = JumpRecorder , BranchRecorder , LineRecorder , ExceptionRecorder , ReturnRecorder
1078
1091
1079
1092
class TestBranchAndJumpEvents (CheckEvents ):
1080
1093
maxDiff = None
@@ -1098,7 +1111,6 @@ def func():
1098
1111
('jump' , 'func' , 4 , 2 ),
1099
1112
('branch' , 'func' , 2 , 2 )])
1100
1113
1101
-
1102
1114
self .check_events (func , recorders = JUMP_BRANCH_AND_LINE_RECORDERS , expected = [
1103
1115
('line' , 'check_events' , 10 ),
1104
1116
('line' , 'func' , 1 ),
@@ -1108,15 +1120,62 @@ def func():
1108
1120
('branch' , 'func' , 3 , 6 ),
1109
1121
('line' , 'func' , 6 ),
1110
1122
('jump' , 'func' , 6 , 2 ),
1123
+ ('line' , 'func' , 2 ),
1111
1124
('branch' , 'func' , 2 , 2 ),
1112
1125
('line' , 'func' , 3 ),
1113
1126
('branch' , 'func' , 3 , 4 ),
1114
1127
('line' , 'func' , 4 ),
1115
1128
('jump' , 'func' , 4 , 2 ),
1129
+ ('line' , 'func' , 2 ),
1116
1130
('branch' , 'func' , 2 , 2 ),
1131
+ ('line' , 'check_events' , 11 )])
1132
+
1133
+ def test_except_star (self ):
1134
+
1135
+ class Foo :
1136
+ def meth (self ):
1137
+ pass
1138
+
1139
+ def func ():
1140
+ try :
1141
+ try :
1142
+ raise KeyError
1143
+ except* Exception as e :
1144
+ f = Foo (); f .meth ()
1145
+ except KeyError :
1146
+ pass
1147
+
1148
+
1149
+ self .check_events (func , recorders = JUMP_BRANCH_AND_LINE_RECORDERS , expected = [
1150
+ ('line' , 'check_events' , 10 ),
1151
+ ('line' , 'func' , 1 ),
1117
1152
('line' , 'func' , 2 ),
1153
+ ('line' , 'func' , 3 ),
1154
+ ('line' , 'func' , 4 ),
1155
+ ('branch' , 'func' , 4 , 4 ),
1156
+ ('line' , 'func' , 5 ),
1157
+ ('line' , 'meth' , 1 ),
1158
+ ('jump' , 'func' , 5 , 5 ),
1159
+ ('jump' , 'func' , 5 , '[offset=114]' ),
1160
+ ('branch' , 'func' , '[offset=120]' , '[offset=122]' ),
1118
1161
('line' , 'check_events' , 11 )])
1119
1162
1163
+ self .check_events (func , recorders = FLOW_AND_LINE_RECORDERS , expected = [
1164
+ ('line' , 'check_events' , 10 ),
1165
+ ('line' , 'func' , 1 ),
1166
+ ('line' , 'func' , 2 ),
1167
+ ('line' , 'func' , 3 ),
1168
+ ('raise' , KeyError ),
1169
+ ('line' , 'func' , 4 ),
1170
+ ('branch' , 'func' , 4 , 4 ),
1171
+ ('line' , 'func' , 5 ),
1172
+ ('line' , 'meth' , 1 ),
1173
+ ('return' , None ),
1174
+ ('jump' , 'func' , 5 , 5 ),
1175
+ ('jump' , 'func' , 5 , '[offset=114]' ),
1176
+ ('branch' , 'func' , '[offset=120]' , '[offset=122]' ),
1177
+ ('return' , None ),
1178
+ ('line' , 'check_events' , 11 )])
1120
1179
1121
1180
class TestSetGetEvents (MonitoringTestBase , unittest .TestCase ):
1122
1181
0 commit comments