L i dZddlmZddlZddlZddlmZddlmZm Z m Z ddl m Z m Z mZddZddZed d d Zed d ZeddZGddZee e eefZeeefZ ddZddZy)z!Bytecode analysis for coverage.py) annotationsN)CodeType)IterableMappingOptional)TArcTLineNoTOffsetc#K|g}|rK|j}|jD]$}t|ts|j |&||rJyyw)z,Iterate over all the code objects in `code`.N)pop co_consts isinstancerappend)codestackcs W/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/coverage/bytecode.py code_objectsrsQ FE yy{ A!X& Q   s5AAAc|Dchc]&}tjj|x}s%|(}}|s Jd||Scc}w)zMake a set of opcodes from instruction names. The names might not exist in this version of Python, skip those if not. z At least one opcode must exist: )disopmapget)op_namesnameopopss rop_setrsN # B$SYY]]4-@'@r'@2 BC B =28*==3 J Cs &AA JUMP_BACKWARDJUMP_BACKWARD_NO_INTERRUPT JUMP_FORWARD RETURN_VALUERETURN_GENERATORNOP NOT_TAKENc2eZdZdZddZddd d dZy) InstructionWalkera]Utility to step through trails of instructions. We have two reasons to need sequences of instructions from a code object: First, in strict sequence to visit all the instructions in the object. This is `walk(follow_jumps=False)`. Second, we want to follow jumps to understand how execution will flow: `walk(follow_jumps=True)`. c||_i|_d}tj|D]}||j|j<|J|j|_yN)rinstsrget_instructionsoffset max_offset)selfrinsts r__init__zInstructionWalker.__init__DsZ 57 ((. +D&*DJJt{{ # +++rTstart_at follow_jumpsc#*Kt}|}||jdzkrq||vry|j||jj |x}r%||r|j t vr |j}j|dz }||jdzkrpyyw)z} Yield instructions starting from `start_at`. Follow unconditional jumps if `follow_jumps` is true. N)setr,addr)ropcode ALWAYS_JUMPS jump_target)r-r2r3seenr+r.s rwalkzInstructionWalker.walkOsut**~ HHV zz~~f--t- DKK<$?!--F aKFt**s BBBN)rrreturnNone)r2r r3boolr>zIterable[dis.Instruction])__name__ __module__ __qualname____doc__r/r=r0rr&r&;s0 &&'T"6: "r0r&c0 tjd}t jdD]}|js|j t vr#|j 2j  d fd }tjt}|||jdz|||j|||j<|jD]#\}}|D]}|||j|%|S)a Calculate branch trails for `code`. `multiline_map` maps line numbers to the first line number of a multi-line statement. Instructions can have a jump_target, where they might jump to next. Some instructions with a jump_target are unconditional jumps (ALWAYS_JUMPS), so they aren't interesting to us, since they aren't the start of a branch possibility. Instructions that might or might not jump somewhere else are branch possibilities. For each of those, we track a trail of instructions. These are lists of instruction offsets, the next instructions that can execute. We follow the trail until we get to a new source line. That gives us the arc from the original instruction's line to the new source line. c4tjtSr() collections defaultdictr7rEr0rzbranch_trails..~s @W@WX[@\r0Fr3ct}d}j|dD]}|j|j|j}| j ||}|r |k7r|}nC|j r|jtvrn#|jtvs|j }n|||fj|yt|d<y)NTr1) r7r=r8r+ line_numberrr;r9r:RETURNSco_firstlinenoupdate) trailsr2 inst_offsetsto_lineinst2l2r from_lineiwalker multiline_maps radd_one_branch_trailz+branch_trails..add_one_branch_trails *-LG xdK   .&&>&**2r2B" / G&&ELL ,L\\W,#222G " 7+,33LA"ut r0r6)r2)rQTBranchTrailsOneSourcer2r r>r?) rHrIr&r=r;r9r:rMrr7r+itemsrP) rrX the_trailsr.rYrQarcoffsetsr+rVrWs `` @@r branch_trailsr_hs-,!, 7 78\ ]J%G % 038  ;;, & $$   !%%i;  %* % % % %6*5)@)@)EVdkkAo>Vd.>.>?"( 4;; #LLN 8LC! 86"3'..w7 8 8c38j r0ci}t|}|jdD]]}|jtvr|j||j </|jt vsB|j dz||j <_|S)zMake a map of unconditional bytecodes jumping to others. Only include bytecodes that do no work and go to another bytecode. FrKr6)r&r=r9r:r;r+NOPS)rjumpsrWr.s r always_jumpsrcsv E%G % 01 ;;, &!%!1!1E$++  [[D !%qE$++  1 Lr0)rrr>zIterable[CodeType])rstrr>zset[int])rrrXzMapping[TLineNo, TLineNo]r> TBranchTrails)rrr>zdict[TOffset, TOffset])rD __future__rrHrtypesrtypingrrrcoverage.typesrr r rrr:rNrar&dictr7rZrer_rcrEr0rrks(" ..11        &&Rhtnc'l:;W445 M M,MM` r0