
    He7                    @   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 ddlmZ ddlmZmZmZmZmZmZmZ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*  G d d      Z+ G d d      Z, edd       G d d             Z- G d de      Z.ee)eeee/   ee/   f      f   Z0 G d d      Z1 G d de1      Z2 G d de1      Z3 G d de1      Z4 G d  d!e1      Z5 G d" d#ejl                        Z7d'd$Z8 G d% d&      Z9y)(zCode parsing for coverage.py.    )annotationsN)	dataclass)CodeType)castAnyCallableDictIterableListOptionalProtocolSequenceSetTuple)env)code_objects)short_stack)NoSource	NotPython)
join_regex	nice_pair)generate_tokens)TArcTLineNoc                      e Zd ZdZ	 	 	 d	 	 	 	 	 	 	 ddZddZddZddZddZddZ	dd	Z
dd
ZddZddZddZ	 d	 	 	 	 	 	 	 ddZy)PythonParserzParse code to find executable lines, excluded lines, etc.

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

    Nc                   |s	|sJ d       |xs d| _         ||| _        nddlm} 	  || j                         | _        || _        | j                  j                  d      | _        t               | _
        t               | _        t               | _        t               | _        t               | _        t               | _        d	| _        i | _        d| _        d| _        y# t        $ r!}t        d| j                    d|       |d}~ww xY w)
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)filenametextcoverage.pythonr   OSErrorr   excludesplitlinesset
statementsexcludedraw_statementsraw_excludedraw_classdefsraw_docstringsshow_tokens
_multiline	_all_arcs_missing_arc_fragments)selfr!   r    r$   r   errs         1/usr/lib/python3/dist-packages/coverage/parser.py__init__zPythonParser.__init__'   s    xM!MM ,H!DI9Y-dmm<	  !%		 5

 ), '*e -0E +.% ,/5 -0E ! 35 ,0<@#U  Y!6t}}oSNOUXXYs   C 	D&DDc                    t        |      }t        j                  |      }t               }t	        | j
                  d      D ](  \  }}|j                  |      s|j                  |       * |S )zFind the lines matching one of a list of regexes.

        Returns a set of line numbers, the lines that contain a match for one
        of the regexes in `regexes`.  The entire line needn't match, just a
        part of it.

           start)r   recompiler'   	enumerater&   searchadd)r2   regexescombinedregex_cmatchesiltexts          r4   lines_matchingzPythonParser.lines_matchingg   s_     g&**X&%!$**A6 	HAu~~e$A	     c           
        | j                   r | j                  | j                         | _        t        j                  }d}d}d}d}d}d}d}d}	| j
                  J t        | j
                        }
|
D ]b  \  }}\  }}\  }}}| j                  rBt        t        j                  j                  ||      ddt        ||f      dd|dd|       |t        j                  k(  r|d	z  }n|t        j                  k(  r|d	z  }n~|t        j                  k(  r#|d
k(  re| j                  j!                  |       nH|t        j"                  k(  r|dk(  rW|	dk(  rR| j                  j%                  t'        ||d	z               xs |}|s|r| j                  j!                  |       |}d}d}n|dk(  r0|r.|| j                  v rd}|r| j                  j!                  |       n|dv r|	d	z  }	n|dv r|	d	z  }	n|t        j(                  k(  r<|t        j                  k(  rj| j*                  j-                  t'        ||d	z                nA|t        j.                  k(  r.|r(||k7  r#t'        ||d	z         D ]  }|| j0                  |<    d}d}|j3                         rA|t        j4                  k7  r.d}|s*|}|r||k  rd}|r| j                  j!                  |       d}|}e |sJt7        | j
                  | j8                        }| j:                  j-                  |j=                                t>        j@                  jB                  r0| j0                  r#tE        | j:                        | j0                  d	<   yyy)zwParse the source to find the interesting facts about its lines.

        A handful of attributes are updated.

        r   FTNz>10 z>520r7   class:@z([{z)]})r    )#r$   rE   r+   tokenINDENTr!   r   r.   printtokenizetok_namegetr   DEDENTNAMEr,   r>   OPintersectionrangeSTRINGr-   updateNEWLINEr/   stripCOMMENT
ByteParserr    r*   _find_statementsr   
PYBEHAVIORmodule_firstline_1min)r2   prev_toktypeindentexclude_indent	excludingexcluding_decorators
first_lineemptyfirst_on_linenestingtokgentoktypettextslineno_elinenorD   should_excludelbyte_parsers                       r4   
_raw_parsezPythonParser._raw_parsew   s7    << $ 3 3DLL AD "LL	%*
"yy$$$ +AG E	#=GULWa,7A%%))'7;w015%  %,,&!ELL(!EJJ&G# &&**73EHH$C<GqL))66uZST7UV 0/ # % ))--g6)/$(	/4,c\m$"3"33/3,+))--g6e^qLGe^qLGELL(5<</ ''..uWgai/HIEMM)'Z"7 #:wqy9 8-7*8
 ${{}H,<,<!<!!(J V~%=$)	 ))--g6$)M"LKE	#P $TYYGK&&{'C'C'EF
 >>,,!$T%8%8!9DOOA 2A,rF   c                    |dk  r!| j                   j                  | |        }|S | j                   j                  ||      }|S )zAReturn the first line number of the statement including `lineno`.r   )r/   rR   )r2   linenos     r4   rg   zPythonParser.first_line   sJ    A:oo))6'F7;;F  __((8FrF   c                J    |D ch c]  }| j                  |       c}S c c}w )zMap the line numbers in `linenos` to the correct first line of the
        statement.

        Returns a set of the first lines.

        rg   )r2   linenosrr   s      r4   first_lineszPythonParser.first_lines   s!     -44q"444s    c                $    | j                  |      S )z)Implement `FileReporter.translate_lines`.)rz   )r2   r&   s     r4   translate_lineszPythonParser.translate_lines   s    &&rF   c                x    |D ch c]'  \  }}| j                  |      | j                  |      f) c}}S c c}}w )z(Implement `FileReporter.translate_arcs`.rx   )r2   arcsabs       r4   translate_arcszPythonParser.translate_arcs   s1    GKLVa#T__Q%78LLLs   ,6c                   	 | j                          | j                  | j                        | _        | j                  | j                  z  }| j                  |z
  }| j                  |      |z
  | _        y# t        j                  t        t        f$ r_}t        |d      r|j                  }n|j                  d   d   }t        d| j                   d|j                  d   d| z         |d}~ww xY w)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.

        rv   r7   r   zCouldn't parse 'z' as Python source: z	 at line N)rt   rP   
TokenErrorIndentationErrorSyntaxErrorhasattrrv   argsr   r    rz   r+   r)   r-   r*   r(   )r2   r3   rv   ignorestartss        r4   parse_sourcezPythonParser.parse_source  s    
	OO (():):;!4!44$$v-**62V; ##%5{C 	sH%!Q"4==/1EF88A;/6(34 	s   A4 4C1AC,,C1c                n    | j                   | j                          | j                   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.

        )r0   _analyze_astr2   s    r4   r~   zPythonParser.arcs  s4     >>!~~)))~~rF   c                l   t        | j                  | j                  | j                        }|j	                          t               | _        |j                  D ]J  \  }}| j                  |      }| j                  |      }||k7  s.| j                  j                  ||f       L |j                  | _        y)zkRun the AstArcAnalyzer and save its results.

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

        N)AstArcAnalyzerr!   r*   r/   analyzer'   r0   r~   rg   r>   missing_arc_fragmentsr1   )r2   aaal1l2fl1fl2s         r4   r   zPythonParser._analyze_ast)  s     TYY(;(;T__Mhh 	/FB//"%C//"%Ccz""C:.		/ '*&?&?#rF   c                   t        j                  t              }| j                         D ]6  \  }}|dk  r|| j                  v r|| j                  v r*||xx   dz  cc<   8 | j
                  D ]  }||v s||xx   dz  cc<    |S )zYGet a count of exits from that each line.

        Excluded lines are excluded.

        r   r7   )collectionsdefaultdictintr~   r)   r,   )r2   exit_countsr   r   rr   s        r4   r   zPythonParser.exit_counts;  s     +6*A*A#*Fiik 
	!FBAvT]]"T]]"Oq O
	! ## 	$AKA!#	$
 rF   c                   | j                   | j                          | j                   J |}|r%|dk  r || k(  r||f|vr||f| j                   v r||}}| j                   j                  ||fdg      }g }|D ]|  \  }}|0|dk  r)| |f| j                   v r| j                  | |      c S d}nd}|j	                  |      }d| d| }	||	d|j	                  |       z  }	|j                  |	       ~ d	j                  |      S )
z5Provide an English sentence describing a missing arc.r   NNz didn't jump to the function exitzdidn't jump to line {lineno}rv   zline rH   z
, because  or )r1   r   rR   missing_arc_descriptionformatappendjoin)
r2   r9   endexecuted_arcsactual_startfragment_pairsmsgssmsgemsgmsgs
             r4   r   z$PythonParser.missing_arc_descriptionV  sG    &&...::: !Gv%L-%LD777 e3E4488%~V( 	JD$|7c{d&A&AA#;;SD#FF=D9D;;c;*D,q/CDKK|K$D#EFFKK	" {{4  rF   )NNN)r!   
str | Noner    r   r$   r   returnNone)r?   strr   set[TLineNo]r   r   )rv   r   r   r   )ry   Iterable[TLineNo]r   r   )r&   r   r   r   )r~   zIterable[TArc]r   	set[TArc])r   r   )r   zdict[TLineNo, int]N)r9   r   r   r   r   zIterable[TArc] | Noner   r   )__name__
__module____qualname____doc__r5   rE   rt   rg   rz   r|   r   r   r~   r   r   r    rF   r4   r   r       s      #"	>A>A >A 	>A
 
>A@ r:h5'M<2
@$> 04	+!+! +! -	+!
 
+!rF   r   c                  D    e Zd ZdZ	 	 d	 	 	 	 	 	 	 ddZd	dZd
dZd
dZy)r]   z3Parse bytecode to understand the structure of code.Nc                    || _         ||| _        y |J 	 t        ||dd      | _        y # t        $ r/}t	        d||j
                  |j                  xs dfz        |d }~ww xY w)NexecT)dont_inheritz5Couldn't parse '%s' as Python source: '%s' at line %dr   )r!   coder;   r   r   r   rv   )r2   r!   r   r    synerrs        r4   r5   zByteParser.__init__  s     	DI'''#D(FN	 K &**fmm.@qO  	s   , 	A$*AA$c                @      fdt         j                        D        S )z~Iterate over all the code objects nested within this one.

        The iteration includes `self` as its first value.

        c              3  L   K   | ]  }t        j                  |         yw))r   N)r]   r!   ).0cr2   s     r4   	<genexpr>z+ByteParser.child_parsers.<locals>.<genexpr>  s     O!
4991--Os   !$)r   r   r   s   `r4   child_parserszByteParser.child_parsers  s     P|DII7NOOrF   c              #    K   t        | j                  d      r+| j                  j                         D ]  \  }}}|s
|  y| j                  j                  ddd   }| j                  j                  ddd   }d}| j                  j                  }d}t        ||      D ]&  \  }}	|r||k7  r| |}||z  }|	dk\  r|	dz  }	||	z  }( ||k7  r| yyw)zYield the line numbers possible in this code object.

        Uses co_lnotab described in Python/compile.c to find the
        line numbers.  Produces a sequence: l0, l1, ...
        co_linesr   N   r7         )r   r   r   	co_lnotabco_firstlinenozip)
r2   ro   linebyte_incrementsline_incrementslast_line_numline_numbyte_num	byte_incr	line_incrs
             r4   _line_numberszByteParser._line_numbers  s      499j)"ii002 
1dJ
 #ii11!$Q$7O"ii11!$Q$7O Myy//HH(+O_(M &$	9=0&(0	)H$&II%& =( )s   :CBCc              #  j   K   | j                         D ]  }|j                         E d{     y7 w)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   )r2   bps     r4   r^   zByteParser._find_statements  s5      $$& 	*B'')))	*)s   '313r   )r!   r   r   zCodeType | Noner    r   r   r   )r   zIterable[ByteParser])r   r   )r   r   r   r   r5   r   r   r^   r   rF   r4   r]   r]     sH    =
 !%#	  	
 
(P>	*rF   r]   T)frozenorderc                  *    e Zd ZU dZded<   dZded<   y)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 `startmsg` 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.

    r   rv    r   causeN)r   r   r   r   __annotations__r   r   rF   r4   r   r     s    
 OE3OrF   r   c                  0    e Zd ZdZ	 	 d	 	 	 	 	 	 	 	 	 ddZy)	TAddArcFnz&The type for AstArcAnalyzer.add_arc().Nc                     y r   r   r2   r9   r   r   r   s        r4   __call__zTAddArcFn.__call__  s     	rF   r   
r9   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   rF   r4   r   r     sB    0
    	
  
rF   r   c                  0    e Zd ZdZddZddZddZddZy)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.
    c                    t         )zProcess break exits.AssertionErrorr2   exitsadd_arcs      r4   process_break_exitszBlock.process_break_exits  
     rF   c                    t         )zProcess continue exits.r   r   s      r4   process_continue_exitszBlock.process_continue_exits   r   rF   c                     y)zProcess raise exits.Fr   r   s      r4   process_raise_exitszBlock.process_raise_exits      rF   c                     y)zProcess return exits.Fr   r   s      r4   process_return_exitszBlock.process_return_exits
  r   rF   Nr   set[ArcStart]r   r   r   bool)r   r   r   r   r   r   r   r   r   rF   r4   r   r     s    rF   r   c                  (    e Zd ZdZddZddZddZy)	LoopBlockz@A block on the block stack representing a `for` or `while` loop.c                0    || _         t               | _        y r   )r9   r'   break_exitsr2   r9   s     r4   r5   zLoopBlock.__init__  s    
*-%rF   c                :    | j                   j                  |       yNT)r   rY   r   s      r4   r   zLoopBlock.process_break_exits  s    &rF   c                b    |D ]*  } ||j                   | j                  |j                         , yr   )rv   r9   r   r2   r   r   xits       r4   r   z LoopBlock.process_continue_exits  s,     	7CCJJ

CII6	7rF   Nr9   r   r   r   r   )r   r   r   r   r5   r   r   r   rF   r4   r   r     s    J0rF   r   c                  (    e Zd ZdZddZddZddZy)FunctionBlockz>A block on the block stack representing a function definition.c                     || _         || _        y r   r9   name)r2   r9   r	  s      r4   r5   zFunctionBlock.__init__#  s    
	rF   c                    |D ]9  } ||j                   | j                   |j                  d| j                         ; y)Nzdidn't except from function Trv   r9   r   r	  r  s       r4   r   z!FunctionBlock.process_raise_exits)  A     	C

TZZK.tyym<	
 rF   c                    |D ]9  } ||j                   | j                   |j                  d| j                         ; y)Nzdidn't return from function Tr  r  s       r4   r   z"FunctionBlock.process_return_exits1  r  rF   N)r9   r   r	  r   r   r   r   )r   r   r   r   r5   r   r   r   rF   r4   r  r  !  s    HrF   r  c                  8    e Zd ZdZddZd	dZd	dZd	dZd	dZy)
TryBlockz6A block on the block stack representing a `try` block.c                    || _         || _        t               | _        t               | _        t               | _        t               | _        y r   )handler_startfinal_startr'   
break_fromcontinue_from
raise_fromreturn_from)r2   r  r  s      r4   r5   zTryBlock.__init__<  s:    *& *-,/E),*-%rF   c                T    | j                   | j                  j                  |       yyNTF)r  r  rY   r   s      r4   r   zTryBlock.process_break_exitsI  s&    'OO""5)rF   c                T    | j                   | j                  j                  |       yyr  )r  r  rY   r   s      r4   r   zTryBlock.process_continue_exitsO  s(    '%%e,rF   c                    | j                   0|D ]*  } ||j                  | j                   |j                         , y| j                  J | j                  j                  |       yr   )r  rv   r   r  r  rY   r  s       r4   r   zTryBlock.process_raise_exitsU  sg    ) C

D$6$6		BC
  ##///OO""5)rF   c                T    | j                   | j                  j                  |       yyr  )r  r  rY   r   s      r4   r   zTryBlock.process_return_exits^  s(    '##E*rF   N)r  TLineNo | Noner  r  r   r   r   )	r   r   r   r   r5   r   r   r   r   r   rF   r4   r  r  :  s    @0rF   r  c                  R    e Zd ZdZd	dZ	 d
	 	 	 	 	 	 	 ddZddZddZddZddZ	y)	WithBlockz7A block on the block stack representing a `with` block.c                    t         j                  j                  sJ || _        t	               | _        t	               | _        t	               | _        y r   )r   r_   exit_through_withr9   r'   r  r  r  r   s     r4   r5   zWithBlock.__init__g  s?     ~~//// 
 *-,/E*-%rF   Nc                    |D ]*  } ||j                   | j                  |j                         , ||j                  |       y)z*Helper to process the four kinds of exits.T)rv   r9   r   rY   )r2   r   r   from_setr  s        r4   _process_exitszWithBlock._process_exitsu  s@      	7CCJJ

CII6	7OOE"rF   c                <    | j                  ||| j                        S r   )r#  r  r   s      r4   r   zWithBlock.process_break_exits  s    ""5'4??CCrF   c                <    | j                  ||| j                        S r   )r#  r  r   s      r4   r   z WithBlock.process_continue_exits  s    ""5'43E3EFFrF   c                &    | j                  ||      S r   )r#  r   s      r4   r   zWithBlock.process_raise_exits  s    ""5'22rF   c                <    | j                  ||| j                        S r   )r#  r  r   s      r4   r   zWithBlock.process_return_exits  s    ""5'43C3CDDrF   r  r   )r   r   r   r   r"  set[ArcStart] | Noner   r   r   )
r   r   r   r   r5   r#  r   r   r   r   r   rF   r4   r  r  e  sQ    A0$ *.	  '	
 
DG3ErF   r  c                      e Zd ZdZddZy)NodeListzA synthetic fictitious node, containing a sequence of nodes.

    This is used when collapsing optimized if-statements, to represent the
    unconditional execution of one of the clauses.

    c                :    || _         |d   j                  | _        y Nr   )bodyrv   )r2   r-  s     r4   r5   zNodeList.__init__  s    	1gnnrF   N)r-  Sequence[ast.AST]r   r   )r   r   r   r   r5   r   rF   r4   r*  r*    s    %rF   r*  c                     d fd}|S )zPA function to make methods for expression-based callable _code_object__ methods.c           	         | j                  |      }| j                  | |d d d|        | j                  || d d d|        y )Nzdidn't run the z	 on line zdidn't finish the )line_for_noder   )r2   noder9   nouns      r4   !_code_object__expression_callablezG_make_expression_code_method.<locals>._code_object__expression_callable  sV    ""4(eVUDOD65'*RSUUFD,>tfIeW*UVrF   )r2   r   r2  ast.ASTr   r   r   )r3  r4  s   ` r4   _make_expression_code_methodr6    s    W -,rF   c                  <   e Zd ZdZ	 	 	 	 	 	 	 	 d/dZd0dZ	 	 d1	 	 	 	 	 	 	 	 	 d2dZd3dZd4dZd5dZ	d6d	Z
e	Zd7d
Ze	Ze	Zd8dZd9dZh dZd:dZ	 	 d1	 	 	 	 	 	 	 d;dZd<dZd=dZd>dZd?dZd@dZdAdZdAdZdAdZdAdZdBdZdCdZeZdDdZ dEdZ!e!Z"eZ#eZ$dFdZ%e&jN                  dk\  rdGdZ(dHd Z)dId!Z*dJd"Z+dKd#Z,dLd$Z-dMd%Z.dNd&Z/e/Z0dOd'Z1dPd(Z2e2Z3dQd)Z4 e5d*      Z6 e5d+      Z7e8jr                  jt                  r e5d,      Z; e5d-      Z< e5d.      Z=yy)Rr   z>Analyze source text with an AST to find executable code paths.c                   t        j                  |      | _        |D ch c]  }|j                  ||       c}| _        || _        t        t        t        j                  dd                  }|rut        d| j                          t        d| j
                          i }t        j                  dk\  rd|d<   t        t        j                  | j                  fdd	i|       t               | _        t!        j"                  t$              | _        g | _        t        t        t        j                  d
d                  | _        y c c}w )NCOVERAGE_AST_DUMP0zStatements: zMultiline map: )   	      rc   include_attributesTCOVERAGE_TRACK_ARCS)astparse	root_noderR   r(   	multiliner   r   osgetenvrO   sysversion_infodumpr'   r~   r   r   listr   block_stackdebug)r2   r!   r(   rC  rr   dump_astdumpkws          r4   r5   zAstArcAnalyzer.__init__  s    48BC19==A.C" BII&93?@AL 123ODNN#345%'F6)#$x #((4>>MdMfMN"u	 5@4K4KD4Q"(* #bii(=sCDE
7 Ds   Ec                    t        j                  | j                        D ]3  }|j                  j                  }t        | d|z   d      }|, ||       5 y)zExamine the AST tree from `root_node` to determine possible arcs.

        This sets the `arcs` attribute to be a set of (from, to) line number
        pairs.

        _code_object__N)r@  walkrB  	__class__r   getattr)r2   r2  	node_namecode_object_handlers       r4   r   zAstArcAnalyzer.analyze  sR     HHT^^, 	*D//I")$0@90Ld"S".#D)		*rF   Nc           
         | j                   r*t        d| d| d|d|       t        t                      | j                  j	                  ||f       ||#| j
                  ||f   j                  ||f       yy)z@Add an arc, including message fragments to use if it is missing.z
Adding possible arc: (z, z): N)rK  rO   r   r~   r>   r   r   r   s        r4   r   zAstArcAnalyzer.add_arc  s|     ::,UG2cU#dXRxPQ+- 		ucl#t/&&s|4;;T4LI  0rF   c                ,    t        | j                        S )z.Yield the blocks in nearest-to-farthest order.)reversedrJ  r   s    r4   nearest_blockszAstArcAnalyzer.nearest_blocks  s    (())rF   c                    |j                   j                  }t        t        t        t
        j                  gt        f      t        | d|z   d            }| ||      S |j                  S )z}What is the right line number to use for this node?

        This dispatches to _line__Node functions where needed.

        _line__N)
rQ  r   r   r   r   r@  ASTr   rR  rv   r2   r2  rS  handlers       r4   r1  zAstArcAnalyzer.line_for_node  sb     NN++	Xswwi012D)i/6
 4= ;;rF   c                l    |j                   r|j                   d   j                  }|S |j                  }|S )zSCompute first line number for things that can be decorated (classes and functions).r   )decorator_listrv   )r2   r2  rv   s      r4   _line_decoratedzAstArcAnalyzer._line_decorated   s8    ((+22F  [[FrF   c                8    | j                  |j                        S r   )r1  valuer2   r2  s     r4   _line__AssignzAstArcAnalyzer._line__Assign  s    !!$**--rF   c                    |j                   rA|j                   d   |j                   d   j                  S |j                  d   j                  S |j                  S r,  )keysrv   valuesrc  s     r4   _line__DictzAstArcAnalyzer._line__Dict  sK    99yy|'yy|*** {{1~,,,;;rF   c                n    |j                   r| j                  |j                   d         S |j                  S r,  )eltsr1  rv   rc  s     r4   _line__ListzAstArcAnalyzer._line__List  s,    99%%diil33;;rF   c                    t         j                  j                  ry|j                  r| j	                  |j                  d         S yNr7   r   )r   r_   r`   r-  r1  rc  s     r4   _line__ModulezAstArcAnalyzer._line__Module!  s7    >>,,YY%%diil33 rF   >   ExprPassAssertAssignDeleteGlobalImportNonlocal	AnnAssign	AugAssign
ImportFromc                X   |j                   j                  }t        t        t        t
        j                  gt        t           f      t        | d|z   d            }| ||      S t        j                  r|| j                  vrt        d|       t        | j                  |            hS )a  Add the arcs for `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 two exits from line 1: they start at line 3 and line 5.

        	_handle__Nz*** Unhandled: )rQ  r   r   r   r   r@  r[  r   r   rR  r   TESTINGOK_TO_DEFAULTRuntimeErrorr1  r\  s       r4   add_arcszAstArcAnalyzer.add_arcs0  s      NN++	XswwiX678D+	148
 4=  {{D$6$66&'?@@ T//5677rF   c                h   ||J |h}|D ]  }| j                  |      }| j                  j                  ||      }|| j                  vr'| j	                  |      }|R|}| j                  |      }|D ])  }| j                  |j                  ||j                         + | j                  |      } |S )au  Add arcs for the body of a compound statement.

        `body` is the body node.  `from_start` is a single `ArcStart` that can
        be the previous line in flow before this body.  `prev_starts` is a set
        of ArcStarts that can be the previous line.  Only one of them should be
        given.

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

        )	r1  rC  rR   r(   find_non_missing_noder   rv   r   r  )	r2   r-  
from_startprev_starts	body_noderv   rg   maybe_body_node
prev_starts	            r4   add_body_arcszAstArcAnalyzer.add_body_arcsQ  s      )))%,K 	3I''	2F++FF;J0"&"<"<Y"G"*+	++I6) J
Z..
8H8HIJ--	2K	3 rF   c                `   | j                  |      }| j                  j                  ||      }|| j                  v r|S t	        t
        t        t        j                  gt
        t        j                     f      t        | d|j                  j                  z   d            }|
 ||      }|S d}|S )a  Search `node` looking for a child that has not been optimized away.

        This might return the node you started with, or it will work recursively
        to find a child node in self.statements.

        Returns a node, or None if none of the node remains.

        
_missing__N)r1  rC  rR   r(   r   r   r   r@  r[  rR  rQ  r   )r2   r2  rv   rg   
missing_fnret_nodes         r4   r  z$AstArcAnalyzer.find_non_missing_noder  s     ##D)^^''7
(KXswwi#'')::;<D,)@)@@$G

 !!$'H  HrF   c                    | j                  t        |j                              }|r|S |j                  r$| j                  t        |j                              S y r   )r  r*  r-  orelse)r2   r2  non_missings      r4   _missing__IfzAstArcAnalyzer._missing__If  sJ     00$))1DE;;--ht{{.CDDrF   c                    g }|j                   D ]'  }| j                  |      }||j                  |       ) |sy t        |      dk(  r|d   S t	        |      S rm  )r-  r  r   lenr*  )r2   r2  non_missing_childrenchildmaybe_childs        r4   _missing__NodeListz!AstArcAnalyzer._missing__NodeList  sn      "YY 	9E44U;K&$++K8	9 $#$)'**,--rF   c                t   | j                  t        |j                              }|sy t        j                         }|j
                  |_        t        j                         |_        |j
                  |j                  _        d|j                  _        t        |d      sJ |j                  |_        g |_
        |S )NTruer-  )r  r*  r-  r@  Whilerv   Nametestidr   r  )r2   r2  
body_nodes	new_whiles       r4   _missing__WhilezAstArcAnalyzer._missing__While  s    //0CD
IIK	%,,		 * 1 1	"	z6***#		rF   c                    |j                   j                  }|dv ryt        |t        j                        r|j
                  dv ryy)z Is this a compile-time constant?)ConstantNameConstantNumr  )r  Falser   	__debug__r  N)rQ  r   
isinstancer@  r  r  )r2   r2  rS  s      r4   is_constant_exprzAstArcAnalyzer.is_constant_expr  s>    NN++	;;chh'ww@@rF   c                j    | j                         D ]   }|j                  || j                        s  y y)z0Add arcs due to jumps from `exits` being breaks.N)rX  r   r   r2   r   blocks      r4   r   z"AstArcAnalyzer.process_break_exits  1    ((* 	E((=	rF   c                j    | j                         D ]   }|j                  || j                        s  y y)z3Add arcs due to jumps from `exits` being continues.N)rX  r   r   r  s      r4   r   z%AstArcAnalyzer.process_continue_exits  s1    ((* 	E++E4<<@	rF   c                j    | j                         D ]   }|j                  || j                        s  y y)z0Add arcs due to jumps from `exits` being raises.N)rX  r   r   r  s      r4   r   z"AstArcAnalyzer.process_raise_exits  r  rF   c                j    | j                         D ]   }|j                  || j                        s  y y)z1Add arcs due to jumps from `exits` being returns.N)rX  r   r   r  s      r4   r   z#AstArcAnalyzer.process_return_exits  s1    ((* 	E))%>	rF   c                v    | j                  |      }t        |d      }| j                  |h       t               S )Nz*the break on line {lineno} wasn't executedr   )r1  r   r   r'   )r2   r2  herebreak_starts       r4   _handle__BreakzAstArcAnalyzer._handle__Break  s6    !!$'t+WX  +/urF   c                   |j                   }|j                   }|j                  }|r<d}|D ].  }| j                  |      }|||k7  r| j                  ||       |}0 |J | j                  ||       |}t        j
                  j                  rt        ||dd       D ]5  \  }}| j                  | j                  |      | j                  |             7 | j                  | j                  |d         |       | j                  || j                  |d                |j                  r:| j                  |j                  d         }	| j                  j                  |	|	      }	|J t        |      hS )zBAdd arcs for things that can be decorated (classes and functions).Nr7   r   )rv   r_  r1  r   r   r_   trace_decorator_line_againr   r-  rC  rR   r   )
r2   r2  	main_linelastdecsdec_node	dec_starttopbot
body_starts
             r4   _handle_decoratedz AstArcAnalyzer._handle_decorated   sd   ![[	#{{""D  ! ..x8	#	T(9LLy1 	!
 ###LLy)D~~88 #D$qr( 3 SHCLL!3!3C!8$:L:LS:QRST//Q8)DY(:(:48(DE
 yy!//		!=
!^^//
JG
rF   c                v    | j                  |      }t        |d      }| j                  |h       t               S )Nz-the continue on line {lineno} wasn't executedr  )r1  r   r   r'   )r2   r2  r  continue_starts       r4   _handle__Continuez AstArcAnalyzer._handle__Continue!  s7    !!$'!$.]^##^$45urF   c                B   | j                  |j                        }| j                  j                  t	        |             t        |d      }| j                  |j                  |      }|D ])  }| j                  |j                  ||j                         + | j                  j                         }t        |t              sJ |j                  }t        |d      }|j                  r$| j                  |j                  |      }||z  }|S |j                  |       |S )Nr8   z'the loop on line {lineno} never startedr  r  z)the loop on line {lineno} didn't complete)r1  iterrJ  r   r   r   r  r-  r   rv   r   popr  r   r  r>   )r2   r2  r9   r  r   r  my_block
else_exitss           r4   _handle__ForzAstArcAnalyzer._handle__For'  s    ""499-	 67e+TU
""499"D 	7CLLUCII6	7##'')(I...$$e+VW
;;++DKKJ+OJZE  IIj!rF   c                    | j                  |j                        }t        |d      }| j                  |j                  |      }t        |d      }|| j                  |j
                  |      z  }|S )N-the condition on line {lineno} was never truer  r  .the condition on line {lineno} was never false)r1  r  r   r  r-  r  )r2   r2  r9   r  r   s        r4   _handle__IfzAstArcAnalyzer._handle__If@  sl    ""499-e+Z[
""499"De+[\
##DKKJ#GGrF   )r;  
   c                4   | j                  |      }|}t               }d}|j                  D ]  }| j                  |j                        }|j                  }t	        |t
        j                        r*|j                  d   }t	        |t
        j                        r*t	        |t
        j                        rd}| j                  ||d       t        |d      }	|| j                  |j                  |	      z  }|} |s|j                  t        d             |S )NFr  Tz+the pattern on line {lineno} always matchedz*the pattern on line {lineno} never matchedr  r  )r1  r'   casespatternr  r@  MatchOrpatternsMatchAsr   r   r  r-  r>   )
r2   r2  r9   
last_startr   had_wildcardcase
case_startr  r  s
             r4   _handle__MatchzAstArcAnalyzer._handle__MatchI  s    &&t,EJEE L

 (!//=
,, #++6%..r2G !#++6gs{{3#'LZ5bc%F
 ++DII*+MM'
(  		Z/\] LrF   c                t    | j                  |      }| j                  |j                  t        |            }|S )Nr  )r1  r  r-  r   r2   r2  r9   r   s       r4   _handle__NodeListz AstArcAnalyzer._handle__NodeListb  s4    ""4(""499%"IrF   c                v    | j                  |      }t        |d      }| j                  |h       t               S )Nz*the raise on line {lineno} wasn't executedr  )r1  r   r   r'   )r2   r2  r  raise_starts       r4   _handle__RaisezAstArcAnalyzer._handle__Raiseg  s6    !!$'t+WX  +/urF   c                v    | j                  |      }t        |d      }| j                  |h       t               S )Nz+the return on line {lineno} wasn't executedr  )r1  r   r   r'   )r2   r2  r  return_starts       r4   _handle__ReturnzAstArcAnalyzer._handle__Returnn  s6    !!$',YZ!!<.1urF   c                F	   |j                   r| j                  |j                   d         }nd }|j                  r| j                  |j                  d         }nd }||J t        ||      }| j                  j                  |       | j                  |      }| j                  |j                  t        |            }|j                  r#d |_	        |j                   r*t               |_        n| j                  j                          t               }|j                   rid }|j                   D ]X  }	| j                  |	      }|| j                  ||       |}d}
t        ||
      }|| j                  |	j                  |      z  }Z |j                  r| j                  |j                  |      }||z  }|j                  r| j                  j                          ||j                  z  |j                   z  |j                  z  |j"                  z  }| j                  |j                  |      }|j                  rt$        j&                  j(                  rj|j                  D ]N  }|j*                  }|j,                  j/                  |      }|D ]  }| j                  |j*                  ||       ! P |j                  }n| j1                  |j                  |      }| j3                  |       |j                   rt$        j&                  j(                  rj|j                   D ]N  }|j*                  }|j,                  j/                  |      }|D ]  }| j                  |j*                  ||       ! P |j                   }n| j1                  |j                   |      }| j5                  |       |j                  r+| j7                  | j1                  |j                  |             |j"                  rt$        j&                  j(                  rj|j"                  D ]N  }|j*                  }|j,                  j/                  |      }|D ]  }| j                  |j*                  ||       ! P |j"                  }n| j1                  |j"                  |      }| j9                  |       |r|}|S )Nr   r  z3the exception caught by line {lineno} didn't happenr  )r  r   )handlersr1  	finalbodyr  rJ  r   r  r-  r   r  r'   r  r  r   r  r  r  r  r   r_   finally_jumps_backrv   r   r   _combine_finally_startsr   r   r   r   )r2   r2  r  r  	try_blockr9   r   handler_exitslast_handler_starthandler_node
from_causer  
final_fromfinal_exits
break_linerv   r   
final_exitbreakscontinue_line	continuesreturn_linereturnss                          r4   _handle__TryzAstArcAnalyzer._handle__Tryu  sN   == ..t}}Q/?@M M>>,,T^^A->?KK (K,CCC]K8		*""4(""499%"I
 >>&*I#}} (+u	$  "'*u==15 $ ^ $ 2 2< @%1LL!3]C%2"R
%m:F
!3!3L4E4ER\!3!]]^ ;;&&t{{&FE>>  "$$%''( $$% %%	&  ,,T^^,TK##>>44&/&:&: K
!+!2!2 * 0 0 7 7v 7 F*5 KJ LL):):FEJKK
 '11F!99):N:NP[\F((0&&>>44)2)@)@ K!.!5!5 - 3 3 : :& : I*5 KJ LL):):FEJKK
 !* 7 7I $ < <Y=T=TVa bI++I6##((001E1E{S $$>>44'0'<'< K!,!3!3 + 1 1 8 8 8 G*5 KJ LL):):FEJKK
 (33G"::9;P;PR]^G))'2 $rF   c                    g }t        |      D ]D  }|j                  s|j                  |j                  j                  |j                               F dj                  |      }|D ch c]  }t        |j                  |       }}|S c c}w )a  Helper for building the cause of `finally` branches.

        "finally" clauses might not execute their exits, and the causes could
        be due to a failure to execute any of the exits in the try block. So
        we use the causes from `starts` as the causes for `exits`.
        r   r   )sortedr   r   r   rv   r   r   )r2   r   r   causesr9   r   r  s          r4   r  z&AstArcAnalyzer._combine_finally_starts  s     F^ 	GE{{ekk000EF	G F#8=>#**e,>> ?s   *Bc                6   | j                  |j                        x}}| j                  |j                        }d}|rd}t        j                  j
                  rd}|r| j                  |j                  d         }| j                  j                  t        |             t        |d      }| j                  |j                  |      }|D ])  }| j                  |j                  ||j                         + t               }| j                  j!                         }	t#        |	t              sJ |j%                  |	j&                         t        |d      }|j(                  r$| j                  |j(                  |      }
||
z  }|S |s|j+                  |       |S )	NFTr   r8   r  r  r  r  )r1  r  r  r   r_   keep_constant_testr-  rJ  r   r   r   r  r   rv   r   r'   r  r  rY   r   r  r>   )r2   r2  r9   to_topconstant_testtop_is_body0r  r   r  r  r  s              r4   _handle__WhilezAstArcAnalyzer._handle__While  s`   ++DII66--dii8L>>,, L''		!5F	 78e+Z[
""499"D 	8CLLVSYY7	8##'')(I...X))*e+[\
;;++DKKJ+OJZE
  !		*%rF   c                0   | j                  |      }t        j                  j                  r%| j                  j                  t        |             | j                  |j                  t        |            }t        j                  j                  r| j                  j                         }t        |t              sJ t        |      h}|r%|D ]  }| j                  |j                  |         |}|j                  r+| j                  | j!                  |j                  |             |j"                  r+| j%                  | j!                  |j"                  |             |j&                  r+| j)                  | j!                  |j&                  |             |S )Nr8   r  )r1  r   r_   r   rJ  r   r  r  r-  r   r  r  r   rv   r  r   r  r  r   r  r   )r2   r2  r9   r   
with_block	with_exitr  s          r4   _handle__WithzAstArcAnalyzer._handle__With  sM   ""4(>>++##IE$:;""499%"I>>++))--/Jj)444!%)I  4CLLU34!$$((001F1F	R ''++001I1I9U %%))001G1GS rF   c                :   | j                  |      }|j                  rX| j                  |j                  t        |             }|D ]+  }| j	                  |j
                  | |j                  d       - y | j	                  | |       | j	                  ||        y )Nr  zdidn't exit the module)r1  r-  r  r   r   rv   r   r2   r2  r9   r   r  s        r4   _code_object__Modulez#AstArcAnalyzer._code_object__Module2  s    ""4(99&&tyyXuf=M&NE VSZZ%<TUV LL%'LL'rF   c                *   | j                  |      }| j                  j                  t        ||j                               | j                  |j                  t        |             }| j                  |       | j                  j                          y )Nr  r  )
r1  rJ  r   r  r	  r  r-  r   r   r  r  s       r4   _code_object__FunctionDefz(AstArcAnalyzer._code_object__FunctionDef=  sq    ""4(E		 JK""4995&9I"J!!%(rF   c                   | j                  |      }| j                  | |       | j                  |j                  t	        |            }|D ]8  }| j                  |j
                  | |j                  d|j                         : y )Nr  zdidn't exit the body of class )r1  r   r  r-  r   rv   r   r	  r  s        r4   _code_object__ClassDefz%AstArcAnalyzer._code_object__ClassDefF  sy    ""4(eVU#""499%"I 	CLL

UFCII0>	rF   lambdazgenerator expressionzdictionary comprehensionzset comprehensionzlist comprehension)r!   r   r(   r   rC  zdict[TLineNo, TLineNo]r   r   r   r   r   )r   zIterable[Block])r2  r5  r   r   )r2  ast.FunctionDefr   r   )r2  z
ast.Assignr   r   )r2  zast.Dictr   r   )r2  zast.Listr   r   )r2  
ast.Moduler   r   )r2  r5  r   r   )r-  r.  r  zArcStart | Noner  r(  r   r   )r2  r5  r   ast.AST | None)r2  ast.Ifr   r  )r2  r*  r   r  )r2  	ast.Whiler   r  )r2  r5  r   r   )r   r   r   r   )r2  z	ast.Breakr   r   )r2  r  r   r   )r2  zast.Continuer   r   )r2  zast.Forr   r   )r2  r  r   r   )r2  z	ast.Matchr   r   )r2  r*  r   r   )r2  z	ast.Raiser   r   )r2  z
ast.Returnr   r   )r2  zast.Tryr   r   )r   r   r   r   r   r   )r2  r  r   r   )r2  zast.Withr   r   )r2  r  r   r   )r2  r  r   r   )r2  zast.ClassDefr   r   )>r   r   r   r   r5   r   r   rX  r1  r`  rd  _line__ClassDefrh  _line__FunctionDef_line__AsyncFunctionDefrk  rn  r}  r  r  r  r  r  r  r  r   r   r   r   r  r  _handle__ClassDefr  r  _handle__AsyncFor_handle__FunctionDef_handle__AsyncFunctionDefr  rF  rG  r  r  r  r  r  r  r  r  _handle__AsyncWithr  r  _code_object__AsyncFunctionDefr	  r6  _code_object__Lambda_code_object__GeneratorExpr   r_   comprehensions_are_functions_code_object__DictComp_code_object__SetComp_code_object__ListCompr   rF   r4   r   r     s   H#F#F !#F *	#F
 
#FJ*"  JJ J 	J
 J 
J * . &O	 )-M
8H '+,0	 $ *	
 
BD	. 2" > *( %, 1 7"	2
m^:6 '	( &?" 8A!=>T!U
~~22!=>X!Y <=P Q!=>R!S 3rF   r   )r3  r   r   z)Callable[[AstArcAnalyzer, ast.AST], None]):r   
__future__r   r@  r   rD  r:   rF  rM   rP   dataclassesr   typesr   typingr   r   r   r	   r
   r   r   r   r   r   r   coverager   coverage.bytecoder   coverage.debugr   coverage.exceptionsr   r   coverage.miscr   r   coverage.phystokensr   coverage.typesr   r   r   r]   r   r   r   TArcFragmentsr   r   r  r  r  r[  r*  r6  r   r   rF   r4   <module>r+     s"   $ " 
  	 	 
   !    
  * & 3 / / (a! a!HG* G*\ $d#  $ 	 	 T4hsmXc]&B CDDE > $E 2(u (V'E 'ET	%sww 	%-n
T n
TrF   