o
    š~Z ²  ã                   @   sˆ  d 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 ddlmZ ddlmZ ddlmZmZmZmZmZ dd	lmZmZmZ dd
lmZmZmZ G dd„ deƒZG dd„ deƒZ G dd„ deƒZ!G dd„ deƒZ"G dd„ deƒZ#G dd„ de $dd¡ƒZ%eddd„ ƒ e&e'ej( )dd¡ƒƒZ*G dd„ deƒZ+G dd „ d eƒZ,e*rÂd!gZ-d"d#„ Z.d&d$d%„Z/dS dS )'zCode parsing for coverage.py.é    N)Úenv)Úrange)Úbytes_to_intsÚstring_class)ÚCodeObjects)Úshort_stack)ÚcontractÚ
join_regexÚnew_contractÚ	nice_pairÚone_of)ÚNoSourceÚ	NotPythonÚStopEverything)Úcompile_unicodeÚgenerate_tokensÚneuter_encoding_declarationc                   @   sŠ   e Zd ZdZedd�ddd„ƒZe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dS )!ÚPythonParserz™Parse code to find executable lines, excluded lines, etc.

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

    zunicode|None©ÚtextNc              
   C   sÔ   |s|sJ dƒ‚|pd| _ || _| js7ddlm} z|| j ƒ| _W n ty6 } z	td| j |f ƒ‚d}~ww || _| j d¡| _t	ƒ | _
t	ƒ | _t	ƒ | _t	ƒ | _t	ƒ | _t	ƒ | _d| _i | _d| _d| _d| _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.

        z*PythonParser needs either text or filenamez<code>r   )Úget_python_sourcezNo source for code: '%s': %sNÚ
F)Úfilenamer   Úcoverage.pythonr   ÚIOErrorr   ÚexcludeÚsplitÚlinesÚsetÚ
statementsÚexcludedÚraw_statementsÚraw_excludedÚraw_classdefsÚraw_docstringsÚshow_tokensÚ
_multilineÚ_byte_parserÚ	_all_arcsÚ_missing_arc_fragments)Úselfr   r   r   r   Úerr© r,   úA/var/www/html/env/lib/python3.10/site-packages/coverage/parser.pyÚ__init__   s4   
ÿ€ÿ
zPythonParser.__init__c                 C   s   | j st| j| jd�| _ | j S )zCreate a ByteParser on demand.)r   )r'   Ú
ByteParserr   r   ©r*   r,   r,   r-   Úbyte_parser\   s   zPythonParser.byte_parserc                 G   sX   t |ƒ}tjr| d¡}t |¡}tƒ }t| jdd�D ]\}}| 	|¡r)| 
|¡ q|S )zêFind 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.

        Úutf8é   ©Ústart)r	   r   ÚPY2ÚdecodeÚreÚcompiler   Ú	enumerater   ÚsearchÚadd)r*   ÚregexesÚcombinedÚregex_cÚmatchesÚiÚltextr,   r,   r-   Úlines_matchingc   s   



€zPythonParser.lines_matchingc                 C   s  | j r
|  | j ¡| _d}d}d}d}tj}d}d}d}t| jƒ}	|	D ]×\}
}\}}\}}}| jrCtdt	j
 |
|
¡t||fƒ||f ƒ |
tjkrM|d7 }n‡|
tjkrW|d8 }n}|
tjkrg|dkrf| j |¡ nm|
tjkrž|dkrˆ|| jv pv|}|s‡|r‡| j |¡ |}d}d}nL|d	kr�|r�|| jv r•d}|r�| j |¡ n6|
tjkr´|tjkr´| j t||d ƒ¡ n |
tjkrÔ|durÐ||krÐt||d ƒD ]}|| j|< qÈd}d}| ¡ r÷|
t	jkr÷d}|du r÷|}|rí||kríd}|rõ| j |¡ d}|
}q"|�s| j | j ¡ ¡ dS dS )
zwParse the source to find the interesting facts about its lines.

        A handful of attributes are updated.

        r   FNTz%10s %5s %-20r %rr3   Úclassú:ú@)r   rC   r"   ÚtokenÚINDENTr   r   r%   ÚprintÚtokenizeÚtok_nameÚgetr   ÚDEDENTÚNAMEr#   r<   ÚOPÚSTRINGr$   Úupdater   ÚNEWLINEr&   ÚstripÚCOMMENTr!   r1   Ú_find_statements)r*   ÚindentÚexclude_indentÚ	excludingÚexcluding_decoratorsÚprev_toktypeÚ
first_lineÚemptyÚfirst_on_lineÚtokgenÚtoktypeÚttextÚslinenoÚ_ÚelinenorB   Úshould_excludeÚlr,   r,   r-   Ú
_raw_parseu   sz   
þ




€
€
€
ÿzPythonParser._raw_parsec                 C   s   | j  ||¡S )z?Return the first line number of the statement including `line`.)r&   rL   )r*   Úliner,   r,   r-   r[   Ð   s   zPythonParser.first_linec                    s   t ‡ fdd„|D ƒƒS )zˆMap the line numbers in `lines` to the correct first line of the
        statement.

        Returns a set of the first lines.

        c                 3   s   � | ]}ˆ   |¡V  qd S ©N©r[   ©Ú.0re   r0   r,   r-   Ú	<genexpr>Û   ó   € z+PythonParser.first_lines.<locals>.<genexpr>)r   ©r*   r   r,   r0   r-   Úfirst_linesÔ   s   zPythonParser.first_linesc                 C   s
   |   |¡S )z)Implement `FileReporter.translate_lines`.)ro   rn   r,   r,   r-   Útranslate_linesÝ   ó   
zPythonParser.translate_linesc                    s   ‡ fdd„|D ƒS )z(Implement `FileReporter.translate_arcs`.c                    s$   g | ]\}}ˆ   |¡ˆ   |¡f‘qS r,   ri   )rk   ÚaÚbr0   r,   r-   Ú
<listcomp>ã   s   $ z/PythonParser.translate_arcs.<locals>.<listcomp>r,   )r*   Úarcsr,   r0   r-   Útranslate_arcsá   s   zPythonParser.translate_arcsc              
   C   sž   z|   ¡  W n, tjtfy2 } zt|dƒr|j}n|jd d }td| j|jd |f ƒ‚d}~ww |  	| j
¡| _| j| jB }| j| }|  	|¡| | _dS )zÁParse source text to find executable lines, excluded lines, etc.

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

        Úlinenor3   r   ú5Couldn't parse '%s' as Python source: '%s' at line %dN)rf   rJ   Ú
TokenErrorÚIndentationErrorÚhasattrrw   Úargsr   r   ro   r"   r    r$   r!   r   )r*   r+   rw   ÚignoreÚstartsr,   r,   r-   Úparse_sourceå   s"   
ÿÿ€û
zPythonParser.parse_sourcec                 C   s   | j du r	|  ¡  | j S )zÃGet 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_astr0   r,   r,   r-   ru   ÿ   s   
zPythonParser.arcsc                 C   sj   t | j| j| jƒ}| ¡  tƒ | _|jD ]\}}|  |¡}|  |¡}||kr.| j 	||f¡ q|j
| _dS )zkRun the AstArcAnalyzer and save its results.

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

        N)ÚAstArcAnalyzerr   r!   r&   Úanalyzer   r(   ru   r[   r<   Úmissing_arc_fragmentsr)   )r*   ÚaaaÚl1Úl2Úfl1Úfl2r,   r,   r-   r€   
  s   

€zPythonParser._analyze_astc                 C   sv   t  t¡}|  ¡ D ]\}}|dk rq	|| jv rq	|| jv rq	||  d7  < q	| jD ]}||v r8||  d8  < q*|S )zYGet a count of exits from that each line.

        Excluded lines are excluded.

        r   r3   )ÚcollectionsÚdefaultdictÚintru   r    r#   )r*   Úexit_countsr…   r†   re   r,   r,   r-   rŒ     s   



€zPythonParser.exit_countsc                 C   s  | j du r	|  ¡  |}|r(|dk r(|| kr(||f|vr(||f| j v r(||}}| j  ||fdg¡}g }|D ]F}|\}}	|	du rZ|dk rX| |f| j v rU|  | |¡  S d}	nd}	|	j|d�}	dj||	d�}
|durw|
d	j|j|d�d
�7 }
| |
¡ q6d |¡S )z5Provide an English sentence describing a missing arc.Nr   ©NNz didn't jump to the function exitzdidn't jump to line {lineno}©rw   zline {start} {emsg})r5   Úemsgz, because {smsg})Úsmsgú or )r)   r€   rL   Úmissing_arc_descriptionÚformatÚappendÚjoin)r*   r5   ÚendÚexecuted_arcsÚactual_startÚfragment_pairsÚmsgsÚfragment_pairr�   r�   Úmsgr,   r,   r-   r’   7  s2   
ÿ

z$PythonParser.missing_arc_description)NNNrh   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r.   Úpropertyr1   rC   rf   r[   ro   rp   rv   r   ru   r€   rŒ   r’   r,   r,   r,   r-   r      s"    =
[	r   c                   @   s<   e Zd ZdZedd�ddd„ƒZdd„ Zd	d
„ Zdd„ ZdS )r/   z3Parse bytecode to understand the structure of code.Úunicoder   Nc              
   C   sv   || _ |r	|| _n!z	t||dƒ| _W n ty) } ztd||j|jf ƒ‚d }~ww dD ]}t| j|ƒs8tdƒ‚q,d S )NÚexecrx   )Ú	co_lnotabÚco_firstlinenozsThis implementation of Python doesn't support code analysis.
Run coverage.py under another Python for this command.)	r   Úcoder   ÚSyntaxErrorr   rœ   rw   r{   r   )r*   r   r¦   r   ÚsynerrÚattrr,   r,   r-   r.   d  s(   
ÿÿ€ÿ	ÿÿÿzByteParser.__init__c                    s   t ˆ jƒ}‡ fdd„|D ƒS )z~Iterate over all the code objects nested within this one.

        The iteration includes `self` as its first value.

        c                 3   s   � | ]
}t ˆ j|d �V  qdS ))r¦   N)r/   r   ©rk   Úcr0   r,   r-   rl   ƒ  s   € z+ByteParser.child_parsers.<locals>.<genexpr>)r   r¦   )r*   Úchildrenr,   r0   r-   Úchild_parsers|  s   
zByteParser.child_parsersc                 c   s–   � t | jjddd… ƒ}t | jjddd… ƒ}d}| jj}d}t||ƒD ]\}}|r9||kr5||fV  |}||7 }||7 }q$||krI||fV  dS dS )a&  Map byte offsets to line numbers in `code`.

        Uses co_lnotab described in Python/compile.c to map byte offsets to
        line numbers.  Produces a sequence: (b0, l0), (b1, l1), ...

        Only byte offsets that correspond to line numbers are included in the
        results.

        r   Né   r3   )r   r¦   r¤   r¥   Úzip)r*   Úbyte_incrementsÚline_incrementsÚlast_line_numÚline_numÚbyte_numÚ	byte_incrÚ	line_incrr,   r,   r-   Ú_bytes_lines…  s    €

ÿzByteParser._bytes_linesc                 c   s,   � |   ¡ D ]}| ¡ D ]\}}|V  qqdS )z´Find 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*   Úbprb   re   r,   r,   r-   rU      s   €ÿþzByteParser._find_statementsr�   )	r�   rž   rŸ   r    r   r.   r­   r·   rU   r,   r,   r,   r-   r/   a  s    	r/   c                   @   s"   e Zd ZdZeed�dd„ ƒZdS )Ú	LoopBlockz@A block on the block stack representing a `for` or `while` loop.r4   c                 C   s   || _ tƒ | _d S rh   )r5   r   Úbreak_exits)r*   r5   r,   r,   r-   r.   ³  s   zLoopBlock.__init__N)r�   rž   rŸ   r    r   r‹   r.   r,   r,   r,   r-   r¹   ±  s    r¹   c                   @   s$   e Zd ZdZeeed�dd„ ƒZdS )ÚFunctionBlockz>A block on the block stack representing a function definition.©r5   Únamec                 C   s   || _ || _d S rh   r¼   )r*   r5   r½   r,   r,   r-   r.   ½  s   
zFunctionBlock.__init__N)r�   rž   rŸ   r    r   r‹   Ústrr.   r,   r,   r,   r-   r»   »  ó    
r»   c                   @   s$   e Zd ZdZeddd�dd„ ƒZdS )ÚTryBlockz6A block on the block stack representing a `try` block.zint|None)Úhandler_startÚfinal_startc                 C   s0   || _ || _tƒ | _tƒ | _tƒ | _tƒ | _d S rh   )rÁ   rÂ   r   Ú
break_fromÚcontinue_fromÚreturn_fromÚ
raise_from)r*   rÁ   rÂ   r,   r,   r-   r.   Ç  s   zTryBlock.__init__N)r�   rž   rŸ   r    r   r.   r,   r,   r,   r-   rÀ   Å  r¿   rÀ   c                       s"   e Zd ZdZd‡ fdd„	Z‡  Z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 `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.

    Nc                    s   t t| ƒ | ||¡S rh   )ÚsuperrÇ   Ú__new__)Úclsrw   Úcause©Ú	__class__r,   r-   rÉ   â  s   zArcStart.__new__rh   )r�   rž   rŸ   r    rÉ   Ú__classcell__r,   r,   rÌ   r-   rÇ   Ö  s    rÇ   ÚArczlineno, causeÚ	ArcStartsc                 C   s   t dd„ | D ƒƒS )Nc                 s   s   � | ]}t |tƒV  qd S rh   )Ú
isinstancerÇ   )rk   Úxr,   r,   r-   rl   è  rm   z<lambda>.<locals>.<genexpr>)Úall)Úseqr,   r,   r-   Ú<lambda>è  s    rÕ   ÚCOVERAGE_AST_DUMPc                   @   s   e Zd ZdZdd„ ZdS )ÚNodeListzÁA 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                 C   s   || _ |d j| _d S ©Nr   )Úbodyrw   )r*   rÙ   r,   r,   r-   r.   õ  s   zNodeList.__init__N)r�   rž   rŸ   r    r.   r,   r,   r,   r-   r×   î  s    r×   c                   @   s~  e Zd ZdZeded�dd„ ƒZdd„ ZdZd	d
„Zdd„ Z	ee
d�dd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zeg d¢ƒZedd�dd„ ƒZedƒedd�dZdd„ƒƒZdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zedd'�d(d)„ ƒZedd'�d*d+„ ƒZedd'�d,d-„ ƒZedd'�d.d/„ ƒZedd�d0d1„ ƒZedd�d2d3„ ƒZeZedd�d4d5„ ƒZedd�d6d7„ ƒZ e Z!eZ"eZ#edd�d8d9„ ƒZ$edd�d:d;„ ƒZ%edd�d<d=„ ƒZ&edd�d>d?„ ƒZ'edd�d@dA„ ƒZ(eddddB�dCdD„ ƒZ)edd�dEdF„ ƒZ*edd�dGdH„ ƒZ+edd�dIdJ„ ƒZ,edd�dKdL„ ƒZ-e-Z.dMdN„ Z/dOdP„ Z0e0Z1dQdR„ Z2dSdT„ Z3e3dUƒZ4e3dVƒZ5e3dWƒZ6e3dXƒZ7e8j9�r=e3dYƒZ:dS dS )[r�   z>Analyze source text with an AST to find executable code paths.r¢   )r   r   c                    s’   t  t|ƒ¡| _t‡ fdd„|D ƒƒ| _ˆ | _tr.td 	| j¡ƒ td 	| j¡ƒ t
| jƒ tƒ | _t t¡| _g | _tttj dd¡ƒƒ| _d S )Nc                 3   s   � | ]	}ˆ   ||¡V  qd S rh   )rL   rj   ©Ú	multiliner,   r-   rl     ó   € z*AstArcAnalyzer.__init__.<locals>.<genexpr>zStatements: {0}zMultiline map: {0}ÚCOVERAGE_TRACK_ARCSr   )ÚastÚparser   Ú	root_noder   r   rÛ   ÚAST_DUMPrI   r“   Úast_dumpru   r‰   rŠ   Úlistrƒ   Úblock_stackÚboolr‹   ÚosÚenvironrL   Údebug)r*   r   r   rÛ   r,   rÚ   r-   r.   ý  s   
zAstArcAnalyzer.__init__c                 C   s>   t  | j¡D ]}|jj}t| d| dƒ}|dur||ƒ qdS )z¨Examine 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Þ   Úwalkrà   rÍ   r�   Úgetattr)r*   ÚnodeÚ	node_nameÚcode_object_handlerr,   r,   r-   r‚     s   €üzAstArcAnalyzer.analyzeNc                 C   sh   | j rtd ||||¡ƒ ttdd�ƒ | j ||f¡ |dus$|dur2| j||f  ||f¡ dS dS )z@Add an arc, including message fragments to use if it is missing.z!
Adding arc: ({}, {}): {!r}, {!r}é   )ÚlimitN)rè   rI   r“   r   ru   r<   rƒ   r”   )r*   r5   r–   r�   r�   r,   r,   r-   Úadd_arc#  s   ÿzAstArcAnalyzer.add_arcc                 C   s
   t | jƒS )z.Yield the blocks in nearest-to-farthest order.)Úreversedrä   r0   r,   r,   r-   Únearest_blocks-  rq   zAstArcAnalyzer.nearest_blocks)Úreturnsc                 C   s.   |j j}t| d| dƒ}|dur||ƒ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)rÍ   r�   rë   rw   ©r*   rì   rí   Úhandlerr,   r,   r-   Úline_for_node1  s
   zAstArcAnalyzer.line_for_nodec                 C   s   |   |j¡S rh   )rø   Úvalue©r*   rì   r,   r,   r-   Ú_line__Assign?  s   zAstArcAnalyzer._line__Assignc                 C   s<   t jdkr|jr|jd d ur|jd jS |jd jS |jS )N)é   é   r   )r   Ú	PYVERSIONÚkeysrw   Úvaluesrú   r,   r,   r-   Ú_line__DictB  s
   zAstArcAnalyzer._line__Dictc                 C   s   |j r|  |j d ¡S |jS rØ   )Úeltsrø   rw   rú   r,   r,   r-   Ú_line__ListN  s   zAstArcAnalyzer._line__Listc                 C   s   |j r|  |j d ¡S dS )Nr   r3   )rÙ   rø   rú   r,   r,   r-   Ú_line__ModuleT  s   zAstArcAnalyzer._line__Module)ÚAssignÚAssertÚ	AugAssignÚDeleteÚExecÚExprÚGlobalÚImportÚ
ImportFromÚNonlocalÚPassÚPrintrÐ   c                 C   s>   |j j}t| d| dƒ}|dur||ƒS 	 tt|  |¡ƒgƒ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__N)	rÍ   r�   rë   ÚOK_TO_DEFAULTrI   r“   r   rÇ   rø   rö   r,   r,   r-   Úadd_arcsa  s   zAstArcAnalyzer.add_arcszfrom_start, prev_startsc                 C   s†   |du r	t |gƒ}|D ]5}|  |¡}| j ||¡}|| jvr-|  |¡}|du r(q|  |¡}|D ]}|  |j||j¡ q/|  	|¡}q|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.

        N)
r   rø   rÛ   rL   r   Úfind_non_missing_noderñ   rw   rË   r  )r*   rÙ   Ú
from_startÚprev_startsÚ	body_noderw   r[   Ú
prev_startr,   r,   r-   Úadd_body_arcs�  s   




zAstArcAnalyzer.add_body_arcsc                 C   sR   |   |¡}| j ||¡}|| jv r|S t| d|jj dƒ}|r%||ƒ}|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)rø   rÛ   rL   r   rë   rÍ   r�   )r*   rì   rw   r[   Ú
missing_fnr,   r,   r-   r  �  s   

ÿz$AstArcAnalyzer.find_non_missing_nodec                 C   s2   |   t|jƒ¡}|r|S |jr|   t|jƒ¡S d S rh   )r  r×   rÙ   Úorelse)r*   rì   Únon_missingr,   r,   r-   Ú_missing__Ifµ  s   zAstArcAnalyzer._missing__Ifc                 C   sP   g }|j D ]}|  |¡}|d ur| |¡ q|sd S t|ƒdkr$|d S t|ƒS )Nr3   r   )rÙ   r  r”   Úlenr×   )r*   rì   Únon_missing_childrenÚchildr,   r,   r-   Ú_missing__NodeListÀ  s   


€z!AstArcAnalyzer._missing__NodeListc                 C   s.   |j j}|dv r
dS |dkr|jdv rdS dS )z Is this a compile-time constant?)ÚNameConstantÚNumr$  ÚName)ÚTrueÚFalseÚNoneÚ	__debug__N)rÍ   r�   Úid)r*   rì   rí   r,   r,   r-   Úis_constant_exprÐ  s   
zAstArcAnalyzer.is_constant_expr)Úexitsc                 C   sT   |   ¡ D ]#}t|tƒr|j |¡  dS t|tƒr'|jdur'|j |¡  dS qdS )z0Add arcs due to jumps from `exits` being breaks.N)ró   rÑ   r¹   rº   rQ   rÀ   rÂ   rÃ   )r*   r,  Úblockr,   r,   r-   Úprocess_break_exitsê  s   
€úz"AstArcAnalyzer.process_break_exitsc                 C   sf   |   ¡ D ],}t|tƒr|D ]}|  |j|j|j¡ q dS t|tƒr0|jdur0|j	 
|¡  dS qdS )z3Add arcs due to jumps from `exits` being continues.N)ró   rÑ   r¹   rñ   rw   r5   rË   rÀ   rÂ   rÄ   rQ   ©r*   r,  r-  Úxitr,   r,   r-   Úprocess_continue_exitsõ  s   
€ùz%AstArcAnalyzer.process_continue_exitsc              
   C   s¢   |   ¡ D ]J}t|tƒr1|jdur"|D ]}|  |j|j|j¡ q dS |jdur0|j 	|¡  dS qt|t
ƒrN|D ]}|  |j|j |jd |j¡¡ q8 dS qdS )z0Add arcs due to jumps from `exits` being raises.Nz!didn't except from function '{0}')ró   rÑ   rÀ   rÁ   rñ   rw   rË   rÂ   rÆ   rQ   r»   r5   r“   r½   r/  r,   r,   r-   Úprocess_raise_exits  s&   


þ

þú÷z"AstArcAnalyzer.process_raise_exitsc              
   C   sr   |   ¡ D ]2}t|tƒr|jdur|j |¡  dS t|tƒr6|D ]}|  |j|j	 |j
d |j¡¡ q  dS qdS )z1Add arcs due to jumps from `exits` being returns.Nz!didn't return from function '{0}')ró   rÑ   rÀ   rÂ   rÅ   rQ   r»   rñ   rw   r5   rË   r“   r½   r/  r,   r,   r-   Úprocess_return_exits  s   

þúüz#AstArcAnalyzer.process_return_exitsc                 C   ó(   |   |¡}t|dd�}|  |g¡ 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rH|jD ]}|   |¡}||kr|  ||¡ |}q|jrH|   |jd ¡}| j ||¡}t|d |ƒD ]}|| jv rG|  ||¡ |}q8tt	|ƒgƒS )zBAdd arcs for things that can be decorated (classes and functions).r   r3   )
rø   Údecorator_listrñ   rÙ   rÛ   rL   r   r   r   rÇ   )r*   rì   ÚlastÚdec_nodeÚ	dec_startÚ
body_startrw   r,   r,   r-   Ú_handle_decorated4  s"   


€
€z AstArcAnalyzer._handle_decoratedc                 C   r4  )Nz-the continue on line {lineno} wasn't executedr5  )rø   rÇ   r1  r   )r*   rì   r6  Úcontinue_startr,   r,   r-   Ú_handle__ContinueN  r9  z AstArcAnalyzer._handle__Continuec                 C   s¢   |   |j¡}| j t|d�¡ t|dd�}| j|j|d�}|D ]}|  |j	||j
¡ q| j ¡ }|j}t|dd�}|jrJ| j|j|d�}||O }|S | |¡ |S )Nr4   z'the loop on line {lineno} never startedr5  ©r  z)the loop on line {lineno} didn't complete)rø   Úiterrä   r”   r¹   rÇ   r  rÙ   rñ   rw   rË   Úpoprº   r  r<   )r*   rì   r5   r  r,  r0  Úmy_blockÚ
else_exitsr,   r,   r-   Ú_handle__ForU  s   

ÿzAstArcAnalyzer._handle__Forc                 C   sL   |   |j¡}t|dd�}| j|j|d�}t|dd�}|| j|j|d�O }|S )Nú-the condition on line {lineno} was never truer5  rB  ú.the condition on line {lineno} was never false)rø   ÚtestrÇ   r  rÙ   r  )r*   rì   r5   r  r,  r,   r,   r-   Ú_handle__Ifn  s   zAstArcAnalyzer._handle__Ifc                 C   ó"   |   |¡}| j|jt|ƒd�}|S ©NrB  ©rø   r  rÙ   rÇ   ©r*   rì   r5   r,  r,   r,   r-   Ú_handle__NodeListw  ó   
z AstArcAnalyzer._handle__NodeListc                 C   r4  )Nz*the raise on line {lineno} wasn't executedr5  )rø   rÇ   r2  r   )r*   rì   r6  Úraise_startr,   r,   r-   Ú_handle__Raise}  ó   
zAstArcAnalyzer._handle__Raisec                 C   r4  )Nz+the return on line {lineno} wasn't executedr5  )rø   rÇ   r3  r   )r*   rì   r6  Úreturn_startr,   r,   r-   Ú_handle__Return…  rT  zAstArcAnalyzer._handle__Returnc                 C   sÄ  |j r|  |j d ¡}nd }|jr|  |jd ¡}nd }t||ƒ}| j |¡ |  |¡}| j|jt|ƒd�}|jrEd |_	|j rDt
g ƒ|_n| j ¡  t
ƒ }|j r{d }|j D ]%}	|  |	¡}|d urf|  ||¡ |}d}
t||
d�}|| j|	j|d�O }qU|jr†| j|j|d�}||O }|jrà| j ¡  ||jB |jB |jB |jB }| j|j|d�}|jrµ|  |  |j|¡¡ |jrÂ|  |  |j|¡¡ |jrÏ|  |  |j|¡¡ |jrÜ|  |  |j|¡¡ |rà|}|S )Nr   rB  z3the exception caught by line {lineno} didn't happenr5  )r  )Úhandlersrø   Ú	finalbodyrÀ   rä   r”   r  rÙ   rÇ   rÁ   r   rÆ   rD  rñ   r  rÃ   rÄ   rÅ   r.  Ú_combine_finally_startsr1  r2  r3  )r*   rì   rÁ   rÂ   Ú	try_blockr5   r,  Úhandler_exitsÚlast_handler_startÚhandler_nodeÚ
from_causer  Ú
final_fromÚfinal_exitsr,   r,   r-   Ú_handle__Try�  s|   


€



ÿþýüÿÿÿÿÿzAstArcAnalyzer._handle__Try)r~   r,  rô   c                    sV   g }t |ƒD ]}|jdur| |jj|jd�¡ qd |¡‰ t‡ fdd„|D ƒƒ}|S )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`.
        NrŽ   r‘   c                 3   s   � | ]	}t |jˆ ƒV  qd S rh   )rÇ   rw   )rk   r0  r5  r,   r-   rl   ï  rÜ   z9AstArcAnalyzer._combine_finally_starts.<locals>.<genexpr>)ÚsortedrË   r”   r“   rw   r•   r   )r*   r~   r,  Úcausesr5   r,   r5  r-   rY  â  s   
€
z&AstArcAnalyzer._combine_finally_startsc                 C   s   g |_ |  |¡S rh   )rX  ra  rú   r,   r,   r-   Ú_handle__TryExceptò  s   
z!AstArcAnalyzer._handle__TryExceptc                 C   sb   g |_ g |_|jd }|jjdkr,|j|jkr,t|jƒdks J ‚|j|_|j |_ |j|_|  |¡S )Nr   Ú	TryExceptr3   )rW  r  rÙ   rÍ   r�   rw   r  ra  )r*   rì   Úfirstr,   r,   r-   Ú_handle__TryFinallyú  s   

z"AstArcAnalyzer._handle__TryFinallyc           
      C   sä   |   |j¡}|  |j¡ }}|rtjs|dkr|  |jd ¡}| j t|d�¡ t	|dd�}| j
|j|d�}|D ]}|  |j||j¡ q8tƒ }| j ¡ }| |j¡ t	|dd�}|jri| j
|j|d�}	||	O }|S |sp| |¡ |S )Nr$  r   r4   rH  r5  rB  rI  )r+  rJ  rø   r   ÚPY3rÙ   rä   r”   r¹   rÇ   r  rñ   rw   rË   r   rD  rQ   rº   r  r<   )
r*   rì   Úconstant_testr5   Úto_topr  r,  r0  rE  rF  r,   r,   r-   Ú_handle__While  s(   
þ
zAstArcAnalyzer._handle__Whilec                 C   rL  rM  rN  rO  r,   r,   r-   Ú_handle__With#  rQ  zAstArcAnalyzer._handle__Withc                 C   sj   |   |¡}|jr%| j|jt| ƒd�}|D ]}|  |j| |jd¡ qd S |  | |¡ |  || ¡ d S )NrB  zdidn't exit the module)rø   rÙ   r  rÇ   rñ   rw   rË   ©r*   rì   r5   r,  r0  r,   r,   r-   Ú_code_object__Module+  s   
ÿz#AstArcAnalyzer._code_object__Modulec                 C   sN   |   |¡}| j t||jd�¡ | j|jt| ƒd�}|  |¡ | j 	¡  d S )Nr¼   rB  )
rø   rä   r”   r»   r½   r  rÙ   rÇ   r3  rD  rO  r,   r,   r-   Ú_code_object__FunctionDef6  s
   

z(AstArcAnalyzer._code_object__FunctionDefc              	   C   sX   |   |¡}|  | |¡ | j|jt|ƒd�}|D ]}|  |j| |jd |j¡¡ qd S )NrB  z#didn't exit the body of class '{0}')	rø   rñ   r  rÙ   rÇ   rw   rË   r“   r½   rm  r,   r,   r-   Ú_code_object__ClassDef?  s   

þÿz%AstArcAnalyzer._code_object__ClassDefc                    s   ‡ fdd„}|S )zFA function to make methods for online callable _code_object__ methods.c              	      sB   |   |¡}|  | |d d ˆ |¡¡ |  || d d ˆ |¡¡ d S )Nzdidn't run the {0} on line {1}z!didn't finish the {0} on line {1})rø   rñ   r“   )r*   rì   r5   ©Únounr,   r-   Ú_code_object__oneline_callableK  s   

þzPAstArcAnalyzer._make_oneline_code_method.<locals>._code_object__oneline_callabler,   )rr  rs  r,   rq  r-   Ú_make_oneline_code_methodI  s   z(AstArcAnalyzer._make_oneline_code_methodÚlambdazgenerator expressionzdictionary comprehensionzset comprehensionzlist comprehensionr�   );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.  r1  r2  r3  r8  r?  Ú_handle__ClassDefrA  rG  Ú_handle__AsyncForÚ_handle__FunctionDefÚ_handle__AsyncFunctionDefrK  rP  rS  rV  ra  rY  rd  rg  rk  rl  Ú_handle__AsyncWithrn  ro  Ú_code_object__AsyncFunctionDefrp  rt  Ú_code_object__LambdaÚ_code_object__GeneratorExpÚ_code_object__DictCompÚ_code_object__SetCompr   rh  Ú_code_object__ListCompr,   r,   r,   r-   r�   ú  s˜    



















T





ÿr�   Úctxc                 C   s$   | dg di t ƒ fv pt| tttfƒS )z:Is `value` simple enough to be displayed on a single line?Nr,   )r   rÑ   r   r‹   Úfloat)rù   r,   r,   r-   Ú_is_simple_valuea  s   þrƒ  c                 C   s|  d| }t | tjƒstd || jj| ¡ƒ dS t| ddƒ}|dur(d | j¡}nd}d || jj|¡}dd	„ t 	| ¡D ƒ}|sHtd
 |¡ƒ dS t
|ƒdkrgt|d d ƒrg|d \}}td |||¡ƒ dS t|ƒ 	 |d }	|D ]B\}}d |	|¡}
t|ƒr‰td |
|¡ƒ qrt |tƒr©td |
¡ƒ |D ]	}t||d ƒ q—td |	¡ƒ qrt|
ƒ t||d ƒ qrtd
 |¡ƒ dS )zhDump the AST for `node`.

        This recursively walks the AST, printing a readable version.

        ú z{0}<{1} {2!r}>Nrw   z @ {0}Ú z
{0}<{1}{2}c                 S   s    g | ]\}}|t vr||f‘qS r,   )ÚSKIP_DUMP_FIELDS)rk   r½   rù   r,   r,   r-   rt   z  s
    þzast_dump.<locals>.<listcomp>z{0}>r3   r   z{0} {1}: {2!r}>z{0}# mro: {1}z, c                 s   s   � | ]}|j V  qd S rh   )r�   rª   r,   r,   r-   rl   ˆ  s   € zast_dump.<locals>.<genexpr>z    z{0}{1}:z	{0} {1!r}z{0} [é   z{0}])rÑ   rÞ   ÚASTrI   r“   rÍ   r�   rë   rw   Úiter_fieldsr  rƒ  r•   Ú__mro__rã   râ   )rì   ÚdepthrV   rw   ÚlinemarkÚheadÚnamed_fieldsÚ
field_namerù   Únext_indentÚprefixÚnr,   r,   r-   râ   h  s@   þ
râ   )r   )0r    rÞ   r‰   ræ   r8   rG   rJ   Úcoverager   Úcoverage.backwardr   r   r   Úcoverage.bytecoder   Úcoverage.debugr   Úcoverage.miscr   r	   r
   r   r   r   r   r   Úcoverage.phystokensr   r   r   Úobjectr   r/   r¹   r»   rÀ   Ú
namedtuplerÇ   rå   r‹   rç   rL   rá   r×   r�   r†  rƒ  râ   r,   r,   r,   r-   Ú<module>   sH     LP

    fô