88import  collections 
99import  dis 
1010from  types  import  CodeType 
11- from  typing  import  Iterable , Optional 
11+ from  typing  import  Iterable , Mapping ,  Optional 
1212
1313from  coverage .types  import  TArc , TLineNo , TOffset 
1414
@@ -31,7 +31,9 @@ def op_set(*op_names: str) -> set[int]:
3131
3232    The names might not exist in this version of Python, skip those if not. 
3333    """ 
34-     return  {op  for  name  in  op_names  if  (op  :=  dis .opmap .get (name ))}
34+     ops  =  {op  for  name  in  op_names  if  (op  :=  dis .opmap .get (name ))}
35+     assert  ops , f"At least one opcode must exist: { op_names }  " 
36+     return  ops 
3537
3638
3739# Opcodes that are unconditional jumps elsewhere. 
@@ -99,10 +101,16 @@ def walk(
99101TBranchTrails  =  dict [TOffset , TBranchTrailsOneSource ]
100102
101103
102- def  branch_trails (code : CodeType , multiline_map : dict [TLineNo , TLineNo ]) ->  TBranchTrails :
104+ def  branch_trails (
105+     code : CodeType ,
106+     multiline_map : Mapping [TLineNo , TLineNo ],
107+ ) ->  TBranchTrails :
103108    """ 
104109    Calculate branch trails for `code`. 
105110
111+     `multiline_map` maps line numbers to the first line number of a 
112+     multi-line statement. 
113+ 
106114    Instructions can have a jump_target, where they might jump to next.  Some 
107115    instructions with a jump_target are unconditional jumps (ALWAYS_JUMPS), so 
108116    they aren't interesting to us, since they aren't the start of a branch 
0 commit comments