o
    v&i                     @  s  d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZmZ ddlmZ ddlmZ ddlmZmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZ ddlm Z m!Z! ddl"m#Z# ddl$m%Z%m&Z& e eZG dd dZ'G dd dZ(edddG dd dZ)G dd deZ*e+e%e,e-ee. ee. f  f Z/G dd dZ0G dd de0Z1G dd de0Z2G dd  d e0Z3d)d%d&Z4G d'd( d(Z5dS )*zCode parsing for coverage.py.    )annotationsN)IterableSequence)	dataclass)CodeType)CallableOptionalProtocolcast)env)code_objects)short_stack)NoSource	NotPython)isolate_module	nice_pair)generate_tokens)TArcTLineNoc                   @  s   e Zd ZdZ			d8d9d	d
Zd:ddZd;ddZejddd<ddZ	d=ddZ
d>ddZd?d"d#Zd;d$d%Zd@d&d'Zd;d(d)Zd?d*d+ZejdAd-d.ZdBd1d2ZdCd4d5ZdCd6d7ZdS )DPythonParserzParse code to find executable lines, excluded lines, etc.

    This information is all based on static analysis: no code execution is
    involved.

    Ntext
str | NonefilenameexcludereturnNonec              
   C  s   |s|sJ d|pd| _ |dur|| _n'ddlm} z|| j | _W n ty; } ztd| j  d| |d}~ww || _d| _t | _	t | _
t | _t | _t | _d| _i | _d| _d| _i | _dS )	z
        Source can be provided as `text`, the text itself, or `filename`, from
        which the text will be read.  Excluded lines are those that match
        `exclude`, a regex string.

        z*PythonParser needs either text or filenamez<code>Nr   )get_python_sourcezNo source for code: 'z': F)r   r   coverage.pythonr   OSErrorr   r   	_ast_rootset
statementsexcludedraw_statementsraw_excludedraw_docstringsshow_tokensmultiline_map	_all_arcs_missing_arc_fragments_with_jump_fixers)selfr   r   r   r   err r-   U/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/coverage/parser.py__init__'   s.   

zPythonParser.__init__regexstrset[TLineNo]c           
        s   t  }d}d}tj| jtjdD ]3}| \}}| jd|| }| jd|| }	| fddt|d |	d D  |}|}q|S )zFind the lines matching a regex.

        Returns a set of line numbers, the lines that contain a match for
        `regex`. The entire line needn't match, just a part of it.
        Handles multiline regex patterns.

        r   )flags
c                 3  s    | ]
} j ||V  qd S Nr'   get).0ir+   r-   r.   	<genexpr>v   s    
z.PythonParser.lines_matching.<locals>.<genexpr>      )	r    refinditerr   	MULTILINEspancountupdaterange)
r+   r0   matches
last_startlast_start_linematchstartend
start_lineend_liner-   r:   r.   lines_matchingf   s   zPythonParser.lines_matchingc                 C  s  | j r| | j | _t| j| _d}d}d}d}d}d}| jdus#J t| j}|D ]\}}	\}
}\}}}| jrKtdt	j
||t|
|f|	|f  |tjkrU|d7 }n_|tjkr_|d8 }nU|tjkr|	dkr|dkr| jt||d }|s|r| j| |}d}n.|	dv r|d7 }n%|	d	v r|d8 }n|tjkr|r||krt||d D ]}|| j|< qd}|	 r|t	jkrd}|s|
}|r||krd}|r| j| q*|st| j| jd
}| j|  | | j| _| jdusJ t | jD ]u}t!|tj"tj#tj$tj%fr:|j&r:|j&d }t!|tj'r:t!|j(tj)r:t!|j(j(t*r:| j+t|j,t-t.|j/d  t!|tj"tj#tj$frot0dd |j1D |j,d}| jt||j,d ro| jt|t-t.|j/d  qdS )zwParse the source to find the interesting facts about its lines.

        A handful of attributes are updated.

        r   FTNz%10s %5s %-20r %rr<   :z([{z)]})r   c                 s  s    | ]}|j V  qd S r5   lineno)r8   dr-   r-   r.   r;      s    z*PythonParser._raw_parse.<locals>.<genexpr>)default)2r   rM   r$   r    r"   r   r   r&   printtokenizetok_namer7   r   tokenINDENTDEDENTOPintersectionrD   addNEWLINEr'   stripCOMMENT
ByteParserr   r#   rC   _find_statementsfirst_linesr   astwalk
isinstanceClassDefFunctionDefAsyncFunctionDefModulebodyExprvalueConstantr1   r%   rP   r
   int
end_linenomindecorator_list)r+   indentexclude_indent	excluding
first_lineemptynestingtokgentoktypettextslineno_elinenoltextshould_excludelbyte_parsernodefirstr-   r-   r.   
_raw_parse}   s   


	







zPythonParser._raw_parsei  )maxsizerP   r   c                 C  s2   |dk r| j | |  }|S | j ||}|S )zAReturn the first line number of the statement including `lineno`.r   r6   )r+   rP   r-   r-   r.   rt      s
   zPythonParser.first_linelinenosIterable[TLineNo]c                   s    fdd|D S )zMap the line numbers in `linenos` to the correct first line of the
        statement.

        Returns a set of the first lines.

        c                   s   h | ]}  |qS r-   rt   r8   r   r:   r-   r.   	<setcomp>   s    z+PythonParser.first_lines.<locals>.<setcomp>r-   )r+   r   r-   r:   r.   ra      s   zPythonParser.first_lineslinesc                 C  s
   |  |S )z)Implement `FileReporter.translate_lines`.)ra   )r+   r   r-   r-   r.   translate_lines      
zPythonParser.translate_linesarcsIterable[TArc]	set[TArc]c                   s    fdd  |D S )z(Implement `FileReporter.translate_arcs`.c                   s$   h | ]\}}  |  |fqS r-   r   )r8   abr:   r-   r.   r      s   $ z.PythonParser.translate_arcs.<locals>.<setcomp>)fix_with_jumps)r+   r   r-   r:   r.   translate_arcs   s   zPythonParser.translate_arcsc              
   C  s   zt | j| _|   W n4 tjttfyA } z$t	|dr"|j
}n|jd d }td| j d|jd d|  |d}~ww | j| jB }| j| }| || | _dS )zParse source text to find executable lines, excluded lines, etc.

        Sets the .excluded and .statements attributes, normalized to the first
        line of multi-line statements.

        rP   r<   r   zCouldn't parse 'z' as Python source: z	 at line N)rb   parser   r   r   rT   
TokenErrorIndentationErrorSyntaxErrorhasattrrP   argsr   r   r"   r%   r#   ra   r!   )r+   r,   rP   ignorestartsr-   r-   r.   parse_source  s&   


zPythonParser.parse_sourcec                 C  s&   | j du r	|   | j dusJ | j S )zGet information about the arcs available in the code.

        Returns a set of line number pairs.  Line numbers have been normalized
        to the first line of multi-line statements.

        N)r(   _analyze_astr:   r-   r-   r.   r     s   
zPythonParser.arcsc                 C  s   | j dusJ t| j| j | j| j}|  |j}| | _| jr&| 	|}t
 | _|D ]\}}| |}| |}||krF| j||f q,|j| _dS )zkRun the AstArcAnalyzer and save its results.

        `_all_arcs` is the set of arcs in the code.

        N)r   AstArcAnalyzerr   r#   r'   analyzer   with_jump_fixersr*   r   r    r(   rt   r[   missing_arc_fragmentsr)   )r+   aaar   l1l2fl1fl2r-   r-   r.   r   %  s   



zPythonParser._analyze_astc                 C  s   t  }t  }|D ]@}|| jv rH|d }|| | j| \}}|| jv r:|| | j| \}}|| || jv s$|||d f || qt ||B | }|S )a  Adjust arcs to fix jumps leaving `with` statements.

        Consider this code:

            with open("/tmp/test", "w") as f1:
                a = 2
                b = 3
            print(4)

        In 3.10+, we get traces for lines 1, 2, 3, 1, 4.  But we want to present
        it to the user as if it had been 1, 2, 3, 4.  The arc 3->1 should be
        replaced with 3->4, and 1->4 should be removed.

        For this code, the fixers dict is {(3, 1): ((1, 4), (3, 4))}.  The key
        is the actual measured arc from the end of the with block back to the
        start of the with-statement.  The values are start_next (the with
        statement to the next statement after the with), and end_next (the end
        of the with-statement to the next statement after the with).

        With nested with-statements, we have to trace through a few levels to
        correct a longer chain of arcs.

        r   r<   )r    r*   r[   )r+   r   	to_removeto_addarcend0
start_nextend_nextr-   r-   r.   r   <  s"   






zPythonParser.fix_with_jumpsdict[TLineNo, int]c                 C  sf   t t}|  D ]'\}}|dksJ d|d| j || jv r"q	|| jv r(q	||  d7  < q	|S )zYGet a count of exits from that each line.

        Excluded lines are excluded.

        r   zl1=z  should be greater than zero in r<   )collectionsdefaultdictrm   r   r   r"   )r+   exit_countsr   r   r-   r-   r.   r   d  s   


zPythonParser.exit_counts
action_msgrJ   c                 C  s*   |du r|dk rd}nd}|j |d}|S )z=Apply some defaulting and formatting to an arc's description.Nr   zjump to the function exitzjump to line {lineno}rO   )format)r+   r   rJ   r-   r-   r.   _finish_action_msgx  s   zPythonParser._finish_action_msgrI   c                 C  s   | j du r|   | j dusJ | j ||fdg}g }|D ]&\}}| ||}d| d| }|dur?|d|j|d 7 }|| qd|S )z5Provide an English sentence describing a missing arc.NNNzline z didn't z	 because rO   z or )r)   r   r7   r   r   appendjoin)r+   rI   rJ   fragment_pairsmsgsmissing_cause_msgr   msgr-   r-   r.   missing_arc_description  s   

z$PythonParser.missing_arc_descriptionc                 C  sL   | j du r|   | j dusJ | j ||fdg}| |d d |}|S )z2Provide an English description of an arc's effect.Nr   r   r<   )r)   r   r7   r   )r+   rI   rJ   r   r   r-   r-   r.   arc_description  s   
zPythonParser.arc_description)NNN)r   r   r   r   r   r   r   r   )r0   r1   r   r2   r   r   )rP   r   r   r   )r   r   r   r2   )r   r   r   r2   )r   r   r   r   )r   r   )r   r   )r   r   rJ   r   r   r1   )rI   r   rJ   r   r   r1   )__name__
__module____qualname____doc__r/   rM   r   	functools	lru_cachert   ra   r   r   r   r   r   r   r   r   r   r   r-   r-   r-   r.   r      s,    	
?

j

	




(


r   c                   @  s>   e Zd ZdZ		ddddZdddZdddZdddZdS )r_   z3Parse bytecode to understand the structure of code.Nr   r1   codeCodeType | Noner   r   r   r   c                 C  s:   || _ |d ur|| _d S |d usJ t||ddd| _d S )NexecT)dont_inherit)r   r   compile)r+   r   r   r   r-   r-   r.   r/     s
   
zByteParser.__init__Iterable[ByteParser]c                   s    fddt  jD S )a|  Iterate over all the code objects nested within this one.

        The iteration includes `self` as its first value.

        We skip code objects named `__annotate__` since they are deferred
        annotations that usually are never run.  If there are errors in the
        annotations, they will be caught by type checkers or other tools that
        use annotations.

        c                 3  s(    | ]}|j d krt j|dV  qdS )__annotate__)r   N)co_namer_   r   )r8   cr:   r-   r.   r;     s    
z+ByteParser.child_parsers.<locals>.<genexpr>)r   r   r:   r-   r:   r.   child_parsers  s   
zByteParser.child_parsersr   c                 c  s&    | j  D ]
\}}}|r|V  qdS )zyYield the line numbers possible in this code object.

        Uses co_lines() to produce a sequence: l0, l1, ...
        N)r   co_lines)r+   r{   liner-   r-   r.   _line_numbers  s   zByteParser._line_numbersc                 c  s"    |   D ]	}| E dH  qdS )zFind the statements in `self.code`.

        Produce a sequence of line numbers that start statements.  Recurses
        into all code objects reachable from `self.code`.

        N)r   r   )r+   bpr-   r-   r.   r`     s   zByteParser._find_statementsr   )r   r1   r   r   r   r   r   r   )r   r   )r   r   )r   r   r   r   r/   r   r   r`   r-   r-   r-   r.   r_     s    

	r_   T)frozenorderc                   @  s&   e Zd ZU dZded< dZded< dS )ArcStarta?  The information needed to start an arc.

    `lineno` is the line number the arc starts from.

    `cause` is an English text fragment used as the `missing_cause_msg` for
    AstArcAnalyzer.missing_arc_fragments.  It will be used to describe why an
    arc wasn't executed, so should fit well into a sentence of the form,
    "Line 17 didn't run because {cause}."  The fragment can include "{lineno}"
    to have `lineno` interpolated into it.

    As an example, this code::

        if something(x):        # line 1
            func(x)             # line 2
        more_stuff()            # line 3

    would have two ArcStarts:

    - ArcStart(1, "the condition on line 1 was always true")
    - ArcStart(1, "the condition on line 1 was never true")

    The first would be used to create an arc from 1 to 3, creating a message like
    "line 1 didn't jump to line 3 because the condition on line 1 was always true."

    The second would be used for the arc from 1 to 2, creating a message like
    "line 1 didn't jump to line 2 because the condition on line 1 was never true."

    r   rP    r1   causeN)r   r   r   r   __annotations__r   r-   r-   r-   r.   r     s   
 r   c                   @  s    e Zd ZdZ		ddddZdS )	TAddArcFnz&The type for AstArcAnalyzer.add_arc().NrI   r   rJ   r   r   r   r   r   c                 C     dS )ab  
        Record an arc from `start` to `end`.

        `missing_cause_msg` is a description of the reason the arc wasn't
        taken if it wasn't taken.  For example, "the condition on line 10 was
        never true."

        `action_msg` is a description of what the arc does, like "jump to line
        10" or "exit from function 'fooey'."

        Nr-   r+   rI   rJ   r   r   r-   r-   r.   __call__  s    zTAddArcFn.__call__r   
rI   r   rJ   r   r   r   r   r   r   r   )r   r   r   r   r   r-   r-   r-   r.   r      s
    r   c                   @  s8   e Zd ZdZddd	Zdd
dZdddZdddZdS )Blocka;  
    Blocks need to handle various exiting statements in their own ways.

    All of these methods take a list of exits, and a callable `add_arc`
    function that they can use to add arcs if needed.  They return True if the
    exits are handled, or False if the search should continue up the block
    stack.
    exitsset[ArcStart]add_arcr   r   boolc                 C  r   )zProcess break exits.Fr-   r+   r   r   r-   r-   r.   process_break_exits%     zBlock.process_break_exitsc                 C  r   )zProcess continue exits.Fr-   r   r-   r-   r.   process_continue_exits)  r   zBlock.process_continue_exitsc                 C  r   )zProcess raise exits.Fr-   r   r-   r-   r.   process_raise_exits-  r   zBlock.process_raise_exitsc                 C  r   )zProcess return exits.Fr-   r   r-   r-   r.   process_return_exits1  r   zBlock.process_return_exitsNr   r   r   r   r   r   )r   r   r   r   r   r   r   r   r-   r-   r-   r.   r     s    



r   c                   @  s.   e Zd ZdZdddZdddZdddZdS )	LoopBlockz@A block on the block stack representing a `for` or `while` loop.rI   r   r   r   c                 C  s   || _ t | _d S r5   )rI   r    break_exitsr+   rI   r-   r-   r.   r/   9  s   zLoopBlock.__init__r   r   r   r   r   c                 C  s   | j | dS NT)r   rC   r   r-   r-   r.   r   ?  s   zLoopBlock.process_break_exitsc                 C  s    |D ]}||j | j|j qdS r   )rP   rI   r   r+   r   r   xitr-   r-   r.   r   C  s   z LoopBlock.process_continue_exitsN)rI   r   r   r   r   )r   r   r   r   r/   r   r   r-   r-   r-   r.   r   6  s
    

r   c                   @  s.   e Zd ZdZddd	ZdddZdddZdS )FunctionBlockz>A block on the block stack representing a function definition.rI   r   namer1   r   r   c                 C     || _ || _d S r5   rI   r   )r+   rI   r   r-   r-   r.   r/   L     
zFunctionBlock.__init__r   r   r   r   r   c                 C  ,   |D ]}||j | j |jd| j qdS )Nzexcept from function TrP   rI   r   r   r   r-   r-   r.   r   R     
z!FunctionBlock.process_raise_exitsc                 C  r   )Nzreturn from function Tr   r   r-   r-   r.   r   \  r   z"FunctionBlock.process_return_exitsN)rI   r   r   r1   r   r   r   )r   r   r   r   r/   r   r   r-   r-   r-   r.   r   I  s
    


r   c                   @  s$   e Zd ZdZdddZdddZdS )TryBlockz6A block on the block stack representing a `try` block.handler_startTLineNo | Nonefinal_startr   r   c                 C  r   r5   )r   r   )r+   r   r   r-   r-   r.   r/   j  r   zTryBlock.__init__r   r   r   r   r   c                 C  s*   | j d ur|D ]}||j| j |j qdS r   )r   rP   r   r   r-   r-   r.   r   p  s   
zTryBlock.process_raise_exitsN)r   r   r   r   r   r   r   )r   r   r   r   r/   r   r-   r-   r-   r.   r   g  s    
r   r   ast.ASTr   tuple[bool, bool]c                 C  s   |  t jd r  dt| jfS   t jd r(  | jdv r%dt| jfS 	 d	S   t jd rG  t| j	t j
rDt| j\}}|| fS 	 d	S  t jd rz dd | jD }tdd |D }|rwt| j	t jrjtnt}d|dd |D fS 	 d	S  d	S )
zIs this a compile-time constant test expression?

    We don't try to mimic all of CPython's optimizations.  We just have to
    handle the kinds of constant expressions people might actually use.

    r-   T)TrueFalser   	__debug__c                 S  s   g | ]}t |qS r-   )is_constant_test_expr)r8   vr-   r-   r.   
<listcomp>  s    z)is_constant_test_expr.<locals>.<listcomp>c                 s  s    | ]\}}|V  qd S r5   r-   )r8   is_constr{   r-   r-   r.   r;         z(is_constant_test_expr.<locals>.<genexpr>c                 s  s    | ]\}}|V  qd S r5   r-   )r8   r{   r  r-   r-   r.   r;     r  )FF)rb   rl   r   rk   NameidevalUnaryOprd   opNotr   operandBoolOpvaluesallOrany)r   is_constantvalretsr	  r-   r-   r.   r   z  s0   
r   c                   @  s  e Zd ZdZdmddZdnddZdoddZdpddZdqddZeZ	drddZ
		dsdtd$d%Zdud'd(Zdvd)d*Zdwd+d,Zdxd.d/ZeZdyd1d2ZeZeZdzd4d5Zd{d6d7Zh d8Zd|d:d;Z		dsd}dBdCZd~dEdFZd~dGdHZd~dIdJZd~dKdLZddNdOZddPdQZeZddSdTZ ddVdWZ!e!Z"eZ#eZ$ddYdZZ%dd\d]Z&dd_d`Z'ddbdcZ(ddedfZ)e)Z*ddhdiZ+ddkdlZ,e,Z-dS )r   a  Analyze source text with an AST to find executable code paths.

    The .analyze() method does the work, and populates these attributes:

    `arcs`: a set of (from, to) pairs of the the arcs possible in the code.

    `missing_arc_fragments`: a dict mapping (from, to) arcs to lists of
    message fragments explaining why the arc is missing from execution::

        { (start, end): [(missing_cause_msg, action_msg), ...], }

    For an arc starting from line 17, they should be usable to form complete
    sentences like: "Line 17 didn't {action_msg} because {missing_cause_msg}".

    NOTE: Starting in July 2024, I've been whittling this down to only report
    arc that are part of true branches.  It's not clear how far this work will
    go.

    r   r1   	root_noder   r!   r2   	multilinedict[TLineNo, TLineNo]r   r   c                   s   || _ || _ fdd|D | _ | _tttdd}|r:td| j  td| j  tt	j
| jddd	 t | _tt| _g | _t | _t | _t | _t | _tttd
d| _d S )Nc                   s   h | ]}  ||qS r-   )r7   r   r  r-   r.   r         z*AstArcAnalyzer.__init__.<locals>.<setcomp>COVERAGE_AST_DUMP0zStatements: zMultiline map: T   )include_attributesrq   COVERAGE_TRACK_ARCS)r   r  r!   r  r   rm   osgetenvrS   rb   dumpr    r   r   r   listr   block_stackcurrent_with_startsall_with_startswith_entries
with_exitsdebug)r+   r   r  r!   r  dump_astr-   r  r.   r/     s"   zAstArcAnalyzer.__init__c                 C  s@   t | jD ]}|jj}t| d| d}|dur|| qdS )zFExamine the AST tree from `self.root_node` to determine possible arcs._code_object__N)rb   rc   r  	__class__r   getattr)r+   r   	node_namecode_object_handlerr-   r-   r.   r     s   zAstArcAnalyzer.analyzedict[TArc, tuple[TArc, TArc]]c                   s   i } fdd j D } jD ]=fdd|D }|sqt|dks-J d| d| }fdd jD }|D ]}|f||ff||f< q=q|S )aK  Get a dict with data for fixing jumps out of with statements.

        Returns a dict.  The keys are arcs leaving a with-statement by jumping
        back to its start.  The values are pairs: first, the arc from the start
        to the next statement, then the arc that exits the with without going
        to the start.

        c                   s(   h | ]}|d   j v r| jvr|qS )r   )r$  r%  r8   r   r:   r-   r.   r     s
    z2AstArcAnalyzer.with_jump_fixers.<locals>.<setcomp>c                       h | ]}|d   kr|d qS )r   r<   r-   r/  rI   r-   r.   r          r<   zExpected one arc, got z with start = c                   r0  )r<   r   r-   r/  r1  r-   r.   r     r2  )r   r$  lenpopr&  )r+   fixers
with_nextsnextsnxtendsrJ   r-   r   r.   r     s   	

 zAstArcAnalyzer.with_jump_fixersr   
ast.Modulec                 C  sR   |  |}|jr | |j}|D ]}| |j| |jd qd S | ||  d S )Nzexit the module)line_for_noderi   process_bodyr   rP   r   r+   r   rI   r   r   r-   r-   r.   _code_object__Module  s   
z#AstArcAnalyzer._code_object__Moduleast.FunctionDefc                 C  sD   |  |}| jt||jd | |j}| | | j  d S )Nr   )	r;  r"  r   r   r   r<  ri   r   r4  )r+   r   rI   r   r-   r-   r.   _code_object__FunctionDef   s
   

z(AstArcAnalyzer._code_object__FunctionDefast.ClassDefc                 C  sB   |  |}| |j}|D ]}| |j| |jd|j qd S )Nzexit class )r;  r<  ri   r   rP   r   r   r=  r-   r-   r.   _code_object__ClassDef	  s
   
 z%AstArcAnalyzer._code_object__ClassDefNrI   r   rJ   r   r   r   c              	   C  s   | j rtd| d| d|d| tt dd | j||f || jv r/| j||f |dus7|durE| j||f ||f dS dS )z@Add an arc, including message fragments to use if it is missing.zAdding possible arc: (z, z): z

)rJ   N)	r'  rS   r   r   r[   r#  r%  r   r   r   r-   r-   r.   r     s    
zAstArcAnalyzer.add_arcIterable[Block]c                 C  s
   t | jS )z.Yield the blocks in nearest-to-farthest order.)reversedr"  r:   r-   r-   r.   nearest_blocks!  r   zAstArcAnalyzer.nearest_blocksc                 C  sV   |j j}ttttjgtf  t| d| d}|dur!||}n|j	}| j
||S )z}What is the right line number to use for this node?

        This dispatches to _line__Node functions where needed.

        _line__N)r*  r   r
   r   r   rb   ASTr   r+  rP   r  r7   )r+   r   r,  handlerr   r-   r-   r.   r;  %  s   
zAstArcAnalyzer.line_for_nodec                 C  s    |j r|j d j}|S |j}|S )zSCompute first line number for things that can be decorated (classes and functions).r   )rp   rP   )r+   r   rP   r-   r-   r.   _line_decorated;  s
   zAstArcAnalyzer._line_decorated
ast.Assignc                 C  s   |  |jS r5   )r;  rk   r+   r   r-   r-   r.   _line__AssignC  s   zAstArcAnalyzer._line__Assignast.Dictc                 C  s2   |j r|j d d ur|j d jS |jd jS |jS Nr   )keysrP   r  rK  r-   r-   r.   _line__DictH  s
   zAstArcAnalyzer._line__Dictast.Listc                 C  s   |j r| |j d S |jS rN  )eltsr;  rP   rK  r-   r-   r.   _line__ListV  s   zAstArcAnalyzer._line__Listc                 C  r   )Nr<   r-   rK  r-   r-   r.   _line__Module\  s   zAstArcAnalyzer._line__Module>   rj   PassAssertAssignDeleteGlobalImportNonlocal	AnnAssign	AugAssign
ImportFromr   c                 C  sz   |j j}ttttjgtt f  t	| d| d}|dur$||}|S t
jr3|| jvr3td| t| |h}|S )a  Find the set of arc starts that exit this node.

        Return a set of ArcStarts, exits from this node to the next. Because a
        node represents an entire sub-tree (including its children), the exits
        from a node can be arbitrarily complex::

            if something(1):
                if other(2):
                    doit(3)
                else:
                    doit(5)

        There are three exits from line 1: they start at lines 1, 3 and 5.
        There are two exits from line 2: lines 3 and 5.

        	_handle__Nz*** Unhandled: )r*  r   r
   r   r   rb   rG  r    r   r+  r   TESTINGOK_TO_DEFAULTRuntimeErrorr;  )r+   r   r,  rH  
arc_startsr-   r-   r.   
node_exitsn  s   

zAstArcAnalyzer.node_exitsri   Sequence[ast.AST]
from_startArcStart | Noneprev_startsset[ArcStart] | Nonec                 C  sv   |du r|du rt  }n
|h}n|du sJ |D ] }| |}|| jvr%q|D ]}| |j||j q'| |}q|S )a  Process the body of a compound statement.

        `body` is the body node to process.

        `from_start` is a single `ArcStart` that starts an arc into this body.
        `prev_starts` is a set of ArcStarts that can all be the start of arcs
        into this body.  Only one of `from_start` and `prev_starts` should be
        given.

        Records arcs within the body by calling `self.add_arc`.

        Returns a set of ArcStarts, the exits from this body.

        N)r    r;  r!   r   rP   r   rd  )r+   ri   rf  rh  	body_noderP   
prev_startr-   r-   r.   r<    s   

zAstArcAnalyzer.process_bodyr   c                 C  &   |   D ]}||| jr dS qdS )z0Add arcs due to jumps from `exits` being breaks.N)rE  r   r   r+   r   blockr-   r-   r.   r     
   z"AstArcAnalyzer.process_break_exitsc                 C  rl  )z3Add arcs due to jumps from `exits` being continues.N)rE  r   r   rm  r-   r-   r.   r     ro  z%AstArcAnalyzer.process_continue_exitsc                 C  rl  )z0Add arcs due to jumps from `exits` being raises.N)rE  r   r   rm  r-   r-   r.   r     ro  z"AstArcAnalyzer.process_raise_exitsc                 C  rl  )z1Add arcs due to jumps from `exits` being returns.N)rE  r   r   rm  r-   r-   r.   r     ro  z#AstArcAnalyzer.process_return_exits	ast.Breakc                 C  (   |  |}t|dd}| |h t S )Nz*the break on line {lineno} wasn't executedr   )r;  r   r   r    )r+   r   herebreak_startr-   r-   r.   _handle__Break     
zAstArcAnalyzer._handle__Breakc                 C  s   |j }|j }|j}|rHd}|D ]}| |}|dur$||kr$| || |}q|dus-J | || |}|jsHJ d|jd| j d|j  |dusNJ t|hS )zBAdd arcs for things that can be decorated (classes and functions).NzOops: node.body = z in @)rP   rp   r;  r   ri   r   r   )r+   r   	main_linelastdecsdec_node	dec_startr-   r-   r.   _handle_decorated  s    
&
z AstArcAnalyzer._handle_decoratedast.Continuec                 C  rq  )Nz-the continue on line {lineno} wasn't executedrr  )r;  r   r   r    )r+   r   rs  continue_startr-   r-   r.   _handle__Continue  rv  z AstArcAnalyzer._handle__Continueast.Forc                 C  s   |  |j}| jt|d t|dd}| j|j|d}|D ]}| |j	||j
 q| j }t|ts7J |j}t|dd}|jrQ| j|j|d}||O }|S || |S )Nr1  z'the loop on line {lineno} never startedrr  rf  z)the loop on line {lineno} didn't complete)r;  iterr"  r   r   r   r<  ri   r   rP   r   r4  rd   r   orelser[   )r+   r   rI   rf  r   r   my_block
else_exitsr-   r-   r.   _handle__For	  s    

zAstArcAnalyzer._handle__Forast.Ifc                 C  st   |  |j}t|j\}}t }|r|r$t|dd}|| j|j|dO }|r(|s8t|dd}|| j|j|dO }|S )N-the condition on line {lineno} was never truerr  r  .the condition on line {lineno} was always true)r;  testr   r    r   r<  ri   r  )r+   r   rI   constant_testr  r   rf  r-   r-   r.   _handle__If"  s   zAstArcAnalyzer._handle__If	ast.Matchc           
      C  s   |  |}|}t }|jD ]!}|  |j}| ||d t|dd}|| j|j|dO }|}q|j}t|t	j
rC|jd }t|t	j
s8t|t	jr\|jd ur\|j}t|t	jr\|jd usNt|t	jok|jd u ok|jd u }	|	sw|t|dd |S )Nz+the pattern on line {lineno} always matchedz*the pattern on line {lineno} never matchedrr  r  )r;  r    casespatternr   r   r<  ri   rd   rb   MatchOrpatternsMatchAsguardr[   )
r+   r   rI   rF   r   case
case_startrf  r  had_wildcardr-   r-   r.   _handle__Match.  s4   



zAstArcAnalyzer._handle__Match	ast.Raisec                 C  rq  )Nz*the raise on line {lineno} wasn't executedrr  )r;  r   r   r    )r+   r   rs  raise_startr-   r-   r.   _handle__RaiseL     
zAstArcAnalyzer._handle__Raise
ast.Returnc                 C  rq  )Nz+the return on line {lineno} wasn't executedrr  )r;  r   r   r    )r+   r   rs  return_startr-   r-   r.   _handle__ReturnS  r  zAstArcAnalyzer._handle__Returnast.Tryc                 C  s,  |j r| |j d }nd }|jr| |jd }nd }|d us&|d us&J t||}| j| | |}| j|jt|d}|jrGd |_	n| j
  t }|j ro|j D ]}| |}d}	t||	d}
|| j|j|
dO }qU|jrz| j|j|d}||O }|jr| j
  |}| j|j|d}|r|}|S )Nr   r  z3the exception caught by line {lineno} didn't happenrr  )rh  )handlersr;  	finalbodyr   r"  r   r<  ri   r   r   r4  r    r  )r+   r   r   r   	try_blockrI   r   handler_exitshandler_node
from_causerf  
final_fromfinal_exitsr-   r-   r.   _handle__TryZ  s>   





zAstArcAnalyzer._handle__Try	ast.Whilec                 C  s   |  |j }}t|j\}}| jt|d t|dd}| j|j|d}|D ]}| 	|j
||j q(t }| j }	t|	tsCJ ||	j t|dd}|jr`| j|j|d}
||
O }|S |sg|| |S )Nr1  r  rr  r  r  )r;  r  r   r"  r   r   r   r<  ri   r   rP   r   r    r4  rd   rC   r   r  r[   )r+   r   rI   to_topr  r{   rf  r   r   r  r  r-   r-   r.   _handle__While  s&   

zAstArcAnalyzer._handle__Whileast.Withc                   s   t jjr fdd|jD }n |g}|D ]} j|  j| q j|j	t
|d d}|d } j| t
|h}|rZ|D ]} |j|  j|j|f qE|}|S )Nc                   s   g | ]}  |jqS r-   )r;  context_expr)r8   itemr:   r-   r.   r    r  z0AstArcAnalyzer._handle__With.<locals>.<listcomp>r  r  )r   
PYBEHAVIORexit_with_through_ctxmgritemsr;  r#  r[   r$  r<  ri   r   remover   rP   r&  )r+   r   r   rI   r   	with_exitr   r-   r:   r.   _handle__With  s    
zAstArcAnalyzer._handle__With)
r   r1   r  r   r!   r2   r  r  r   r   r   )r   r.  )r   r:  r   r   )r   r?  r   r   )r   rA  r   r   r   r   )r   rC  )r   r   r   r   )r   r?  r   r   )r   rJ  r   r   )r   rM  r   r   )r   rQ  r   r   )r   r:  r   r   )r   r   r   r   )ri   re  rf  rg  rh  ri  r   r   )r   r   r   r   )r   rp  r   r   )r   r?  r   r   )r   r~  r   r   )r   r  r   r   )r   r  r   r   )r   r  r   r   )r   r  r   r   )r   r  r   r   )r   r  r   r   )r   r  r   r   )r   r  r   r   ).r   r   r   r   r/   r   r   r>  r@  _code_object__AsyncFunctionDefrB  r   rE  r;  rI  rL  _line__ClassDefrP  _line__FunctionDef_line__AsyncFunctionDefrS  rT  ra  rd  r<  r   r   r   r   ru  r}  _handle__ClassDefr  r  _handle__AsyncFor_handle__FunctionDef_handle__AsyncFunctionDefr  r  r  r  r  _handle__TryStarr  r  _handle__AsyncWithr-   r-   r-   r.   r     s`    

&













&
/











7

r   )r   r   r   r   )6r   
__future__r   rb   r   r   r  r>   rV   rT   collections.abcr   r   dataclassesr   typesr   typingr   r   r	   r
   coverager   coverage.bytecoder   coverage.debugr   coverage.exceptionsr   r   coverage.miscr   r   coverage.phystokensr   coverage.typesr   r   r   r_   r   r   dictr!  tupler1   TArcFragmentsr   r   r   r   r   r   r-   r-   r-   r.   <module>   sH      
=" 
