o
    v&i
                     @  s   d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	m
Z
 ddlmZmZmZ d#ddZd$ddZedddZeddZeddZG dd dZee
e ee f Zeeef Zd%ddZd&d!d"ZdS )'z!Bytecode analysis for coverage.py    )annotationsN)CodeType)IterableMappingOptional)TArcTLineNoTOffsetcoder   returnIterable[CodeType]c                 c  sF    | g}|r!|  } | jD ]}t|tr|| q| V  |sdS dS )z,Iterate over all the code objects in `code`.N)pop	co_consts
isinstancer   append)r
   stackc r   W/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/coverage/bytecode.pycode_objects   s   


r   op_namesstrset[int]c                    s(    fdd| D }|sJ d|  |S )zMake a set of opcodes from instruction names.

    The names might not exist in this version of Python, skip those if not.
    c                   s    h | ]}t j|  r qS r   )disopmapget).0nameopr   r   	<setcomp>"   s     zop_set.<locals>.<setcomp>z At least one opcode must exist: r   )r   opsr   r   r   op_set   s   r"   JUMP_BACKWARDJUMP_BACKWARD_NO_INTERRUPTJUMP_FORWARDRETURN_VALUERETURN_GENERATORNOP	NOT_TAKENc                   @  s,   e Zd ZdZdddZdd	d
dddZdS )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)`.
    r
   r   r   Nonec                 C  sD   || _ i | _d }t|D ]}|| j|j< q|d usJ |j| _d S N)r
   instsr   get_instructionsoffset
max_offset)selfr
   instr   r   r   __init__D   s   zInstructionWalker.__init__r   Tstart_atfollow_jumpsr5   r	   r6   boolIterable[dis.Instruction]c                c  sz    t  }|}|| jd k r;||v rdS || | j| }r.|V  |r.|jtv r.|j}q|d7 }|| jd k sdS dS )z}
        Yield instructions starting from `start_at`.  Follow unconditional
        jumps if `follow_jumps` is true.
              N)setr0   addr-   r   opcodeALWAYS_JUMPSjump_target)r1   r5   r6   seenr/   r2   r   r   r   walkO   s   
zInstructionWalker.walkN)r
   r   r   r+   )r5   r	   r6   r7   r   r8   )__name__
__module____qualname____doc__r3   rA   r   r   r   r   r*   ;   s
    
r*   multiline_mapMapping[TLineNo, TLineNo]TBranchTrailsc           	        s   t dd }t jddD ]U}|jsq|jtv rq|jdu r%qd fdd}t t	}|||j
d d |||jd |||j
< | D ]\}}|D ]}|| | | qYqSq|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.

    c                   S  s
   t tS r,   )collectionsdefaultdictr;   r   r   r   r   <lambda>~   s   
 zbranch_trails.<locals>.<lambda>Fr6   NtrailsTBranchTrailsOneSourcer5   r	   r   r+   c                   s   t  }d }j|ddD ]4}||j |j}|d ur!||}|r+|kr+|} n|jr5|jtvr5 n|jt	v r@ j
 } nq|d urP| |f | d S t  | d < d S )NTr4   )r;   rA   r<   r/   line_numberr   r?   r=   r>   RETURNSco_firstlinenoupdate)rM   r5   inst_offsetsto_lineinst2l2r
   	from_lineiwalkerrF   r   r   add_one_branch_trail   s&   
z+branch_trails.<locals>.add_one_branch_trailr:   )r5   )rM   rN   r5   r	   r   r+   )rI   rJ   r*   rA   r?   r=   r>   rO   r   r;   r/   itemsrR   )	r
   rF   
the_trailsr2   rZ   rM   arcoffsetsr/   r   rW   r   branch_trailsh   s,   


r_   dict[TOffset, TOffset]c                 C  sT   i }t | }|jddD ]}|jtv r|j||j< q|jtv r'|jd ||j< q|S )zMake a map of unconditional bytecodes jumping to others.

    Only include bytecodes that do no work and go to another bytecode.
    FrL   r:   )r*   rA   r=   r>   r?   r/   NOPS)r
   jumpsrY   r2   r   r   r   always_jumps   s   

rc   )r
   r   r   r   )r   r   r   r   )r
   r   rF   rG   r   rH   )r
   r   r   r`   )rE   
__future__r   rI   r   typesr   typingr   r   r   coverage.typesr   r   r	   r   r"   r>   rP   ra   r*   dictr;   rN   rH   r_   rc   r   r   r   r   <module>   s6   

)
P