
    3 f)                     f   d Z ddlmZ ddlZddlZddlZddlmZ 	 ddlZddlm	Z	 n# e
$ r ddlmZm	Z	 Y nw xY wdZ G d d	e          Z G d
 de          Z G d de          Z G d de          Z G d de          ZddZddZd ZddZedk    r eej        dd                    dS dS )z Meager code path measurement tool.
    Ned Batchelder
    http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html
    MIT License.
    )with_statementN)defaultdict)iter_child_nodes)astr   z0.7.0c                   *    e Zd ZdZd Zd Zd Zd ZdS )
ASTVisitorz'Performs a depth-first walk of the AST.c                 "    d | _         i | _        d S N)node_cacheselfs    </var/www/equiseq/venv/lib/python3.11/site-packages/mccabe.py__init__zASTVisitor.__init__   s    	    c                 F    t          |          D ]} | j        |g|R   d S r
   )r   dispatch)r   r   argschilds       r   defaultzASTVisitor.default   s@    %d++ 	( 	(EDM%'$'''''	( 	(r   c                     || _         |j        }| j                            |          }|/|j        }t          | j        d|z   | j                  }|| j        |<    ||g|R  S )Nvisit)r   	__class__r   get__name__getattrvisitorr   )r   r   r   klassmeth	classNames         r   r   zASTVisitor.dispatch!   sm    	{u%%<I4<9)<dlKKD!%DKtD 4    r   c                 H    || _         | j        |_         | j        |g|R   dS )z&Do preorder walk of tree using visitorN)r   r   r   )r   treer   r   s       r   preorderzASTVisitor.preorder+   s2    d"T""""""r   N)r   
__module____qualname____doc__r   r   r   r#    r   r   r   r      sV        11  ( ( (! ! !# # # # #r   r   c                   "    e Zd ZddZd Zd ZdS )PathNodecirclec                 "    || _         || _        d S r
   )namelook)r   r,   r-   s      r   r   zPathNode.__init__3   s    				r   c                 h    t          d| j        | j        |                                 fz             d S )Nznode [shape=%s,label="%s"] %d;)printr-   r,   dot_idr   s    r   to_dotzPathNode.to_dot7   s>    .Ity$++--21 1 	2 	2 	2 	2 	2r   c                      t          |           S r
   )idr   s    r   r0   zPathNode.dot_id;   s    $xxr   N)r*   )r   r$   r%   r   r1   r0   r'   r   r   r)   r)   2   sF           2 2 2    r   r)   c                   (    e Zd ZddZd Zd Zd ZdS )	PathGraphr   c                 p    || _         || _        || _        || _        t	          t
                    | _        d S r
   )r,   entitylinenocolumnr   listnodes)r   r,   r7   r8   r9   s        r   r   zPathGraph.__init__@   s1    	 &&


r   c                 Z    | j         |                             |           g | j         |<   d S r
   )r;   append)r   n1n2s      r   connectzPathGraph.connectG   s+    
2b!!!
2r   c                 8   t          d           | j        D ]}|                                 | j                                        D ]C\  }}|D ];}t          |                                d|                                d           <Dt          d           d S )Nz
subgraph {z -- ;})r/   r;   r1   itemsr0   )r   r   nextsnexts       r   r1   zPathGraph.to_dotL   s    lJ 	 	DKKMMMM:++-- 	D 	DKD% D DT[[]]]]DKKMMMMBCCCCDc




r   c                     t          d | j                                        D                       }t          | j                  }||z
  dz   S )zG Return the McCabe complexity for the graph.
            V-E+2
        c                 ,    g | ]}t          |          S r'   )len).0ns     r   
<listcomp>z(PathGraph.complexity.<locals>.<listcomp>Y   s    ===AQ===r      )sumr;   valuesrI   )r   	num_edges	num_nodess      r   
complexityzPathGraph.complexityU   sK     ==):):)<)<===>>	
OO	9$q((r   N)r   )r   r$   r%   r   r@   r1   rR   r'   r   r   r5   r5   ?   sU        ' ' ' '  
  ) ) ) ) )r   r5   c                        e Zd ZdZ fdZd Zd Zd ZeZd Z	d Z
d Z fd	Zd
 ZexZxZZd ZddZd Zd ZeZd ZeZ xZS )PathGraphingAstVisitorz\ A visitor for a parsed Abstract Syntax Tree which finds executable
        statements.
    c                     t          t          |                                            d| _        i | _        |                                  d S )N )superrT   r   	classnamegraphsreset)r   r   s    r   r   zPathGraphingAstVisitor.__init__c   s?    $d++44666

r   c                 "    d | _         d | _        d S r
   )graphtailr   s    r   rZ   zPathGraphingAstVisitor.reseti   s    
			r   c                 :    |D ]}|                      |           d S r
   )r   )r   	node_listr   s      r   dispatch_listz$PathGraphingAstVisitor.dispatch_listm   s0     	  	 DMM$	  	 r   c                    | j         r| j         |j        }n|j        }d|j        |j        |fz  }| j        |                     |          }|| _        |                     |j                   t          dd          }| j        
                    | j        |           | j        
                    ||           || _        d S t          |||j        |j                  | _        t          |          }|| _        |                     |j                   | j        | j        | j         |j        <   |                                  d S )Nz	%d:%d: %rrV   pointr-   )rX   r,   r8   
col_offsetr\   appendPathNoder]   r`   bodyr)   r@   r5   rY   rZ   )r   r   r7   r,   pathnodebottoms         r   visitFunctionDefz'PathGraphingAstVisitor.visitFunctionDefq   s0   > 	#~~tyy9FFYFdk4?FCC:!**400H DIty)))bw///FJty&111Jx000DIII"4doNNDJ~~H DIty)))@D
DK$..$))<=JJLLLLLr   c                     | j         }| xj         |j        dz   z  c_         |                     |j                   || _         d S )N.)rX   r,   r`   rf   )r   r   old_classnames      r   visitClassDefz$PathGraphingAstVisitor.visitClassDef   s@    $)c/)49%%%&r   c                     | j         sd S t          |          }| j                            | j         |           || _         |S r
   )r]   r)   r\   r@   )r   r,   rg   s      r   re   z%PathGraphingAstVisitor.appendPathNode   sB    y 	FD>>
49h///	r   c                 \    |j         d}n|j         }d|z  }|                     |           d S )Nr   zStmt %d)r8   re   )r   r   r8   r,   s       r   visitSimpleStatementz+PathGraphingAstVisitor.visitSimpleStatement   s<    ;FF[F6!D!!!!!r   c                     t          |t          j                  r|                     |           d S  t	          t
          |           j        |g|R   d S r
   )
isinstancer   stmtrp   rW   rT   r   )r   r   r   r   s      r   r   zPathGraphingAstVisitor.default   s^    dCH%% 	E%%d+++++7E($//7DtDDDDDDr   c                 F    d|j         z  }|                     ||           d S )NzLoop %dr8   	_subgraphr   r   r,   s      r   	visitLoopz PathGraphingAstVisitor.visitLoop   s(    4;&tT"""""r   c                 F    d|j         z  }|                     ||           d S )NzIf %dru   rw   s      r   visitIfzPathGraphingAstVisitor.visitIf   s(    $tT"""""r   r'   c                 V   | j         ut          |||j        |j                  | _         t	          |          }|                     |||           | j         | j        | j        |<   |                                  dS | 	                    |          }|                     |||           dS )z?create the subgraphs representing any `if` and `for` statementsN)
r\   r5   r8   rd   r)   _subgraph_parserY   rX   rZ   re   )r   r   r,   extra_blocksrg   s        r   rv   z PathGraphingAstVisitor._subgraph   s    :"4t{DOLLDJ~~H  x>>>;?:DK$..$$78JJLLLLL**400H  x>>>>>r   c                 (   g }|| _         |                     |j                   |                    | j                    |D ]=}|| _         |                     |j                   |                    | j                    >|j        r<|| _         |                     |j                   |                    | j                    n|                    |           |r:t          dd          }|D ]}| j                            ||           || _         dS dS )z@parse the body and any `else` block of `if` and `for` statementsrV   rb   rc   N)r]   r`   rf   r=   orelser)   r\   r@   )r   r   rg   r}   
loose_endsextrarh   les           r   r|   z&PathGraphingAstVisitor._subgraph_parse   s,   
	49%%%$)$$$! 	) 	)E DIuz***di((((; 	( DIt{+++di((((h''' 	bw///F  / /
""2v....DIII		 	r   c                 T    d|j         z  }|                     |||j                   d S )NzTryExcept %d)r}   )r8   rv   handlersrw   s      r   visitTryExceptz%PathGraphingAstVisitor.visitTryExcept   s.    +tT>>>>>r   c                 x    d|j         z  }|                     |           |                     |j                   d S )NzWith %d)r8   re   r`   rf   rw   s      r   	visitWithz PathGraphingAstVisitor.visitWith   s>    4;&D!!!49%%%%%r   )r'   )r   r$   r%   r&   r   rZ   r`   ri   visitAsyncFunctionDefrm   re   rp   r   rx   visitAsyncForvisitFor
visitWhilerz   rv   r|   r   visitTryr   visitAsyncWith__classcell__)r   s   @r   rT   rT   ^   s4                     4 -' ' '  " " "E E E E E# # # -65M5Hz# # #? ? ? ?  ,? ? ? H& & &
 NNNNNr   rT   c                   ^    e Zd ZdZdZeZdZdZdZ	d Z
ed             Zed             Zd	 Zd
S )McCabeCheckerz%McCabe cyclomatic complexity checker.mccabeC901zC901 %r is too complex (%d)c                     || _         d S r
   )r"   )r   r"   filenames      r   r   zMcCabeChecker.__init__   s    			r   c                 
   d}ddt           ddd}t          |dd           }t          |t                    r?|                    d            |j        |fi | |j                            d	           d S  |j        |fi | d S )
Nz--max-complexityr   storezMcCabe complexity thresholdTrue)r   actiontypehelpparse_from_configconfig_optionsr   zmax-complexity)intr   rr   r:   pop
add_optionr   r=   )clsparserflagkwargsconfig_optss        r   add_optionszMcCabeChecker.add_options   s    !1!'
 
 f&6==k4(( 	.JJ*+++Fd--f---!(()9:::::Fd--f-----r   c                 8    t          |j                  | _        d S r
   )r   max_complexity)r   optionss     r   parse_optionszMcCabeChecker.parse_options  s     !788r   c              #   l  K   | j         dk     rd S t                      }|                    | j        |           |j                                        D ]a}|                                | j         k    rB| j        |j        |                                fz  }|j	        |j
        |t          |           fV  bd S )Nr   )r   rT   r#   r"   rY   rO   rR   _error_tmplr7   r8   r9   r   )r   r   r\   texts       r   runzMcCabeChecker.run  s      ""F(**G,,,^**,, 	C 	CE!!D$777'5<9I9I9K9K*LLlEL$T

BBBB	C 	Cr   N)r   r$   r%   r&   r,   __version__version_coder   r   r   classmethodr   r   r   r'   r   r   r   r      s        //DGE/KN   . . [.$ 9 9 [9C C C C Cr   r      stdinc                    	 t          | |dt          j                  }nP# t          $ rC t	          j                    d         }t          j                            d|d|d           Y dS w xY wg }|t          _	        t          ||          
                                D ]"\  }}}}	|                    d|||fz             #t          |          dk    rdS t          d                    |                     t          |          S )Nexec   zUnable to parse z: 
r   z%s:%d:1: %s)compiler   PyCF_ONLY_ASTSyntaxErrorsysexc_infostderrwriter   r   r   r=   rI   r/   join)
code	thresholdr   r"   ecomplxr8   offsetr   checks
             r   get_code_complexityr     s   tXvs/@AA   LNN1
xxxCDDDqq
 F#,M '4T8'D'D'H'H'J'J @ @#emx&>>????
6{{aq	$))F

v;;s    A	A,+A,c                 D    t          |           }t          |||           S )z"Returns the complexity of a module)r   )_readr   )module_pathr   r   s      r   get_module_complexityr   $  s$    DtYEEEEr   c                    dt           j        cxk     rdk     rAn n>t          | d          5 }|                                cd d d            S # 1 swxY w Y   d S dt           j        cxk    rdk     rn d S 	 	 t          | d          5 }t	          j        |j                  \  }}d d d            n# 1 swxY w Y   n\# t          t          t          f$ rB t          | d          5 }|                                cd d d            cY S # 1 swxY w Y   Y nw xY wt          | d|          5 }|                                cd d d            S # 1 swxY w Y   d S d S )	N)rM      )   r   rU)   r   rbzlatin-1)encodingr)
r   version_infoopenreadtokenizedetect_encodingreadlineLookupErrorr   UnicodeError)r   fr   _s       r   r   r   *  s    ))))6)))))(D!! 	Q6688	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 		3#	,	,	,	,f	,	,	,	,	,	,#	 h%% E ( 8 D D1E E E E E E E E E E E E E E E[,7 	  	  	 h333  qvvxx                                       	  (C(333 	q6688	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 
-	,s}   AAA6B; B/#B; /B33B; 6B37B; ;(D#D7DD
	
DD
	DD)E

EEc                 ^   | t           j        dd          } t          j                    }|                    ddddd           |                    dd	d
ddd           |                    |           \  }}t          |d                   }t          ||d         dt          j	                  }t                      }|                    ||           |j        rtt          d           |j                                        D ]:}|j        r|                                |j        k    r|                                 ;t          d           d S |j                                        D ]F}|                                |j        k    r't          |j        |                                           Gd S )Nr   z-dz--dotdotzoutput a graphviz dot file
store_true)destr   r   z-mz--minr   zminimum complexity for outputr   )r   r   r   r   r   r   zgraph {rC   )r   argvoptparseOptionParserr   
parse_argsr   r   r   r   rT   r#   r   r/   rY   rO   r   rR   r1   r,   )r   oparr   r   r   r"   r   r\   s           r   mainr   ;  s   |x| ""DOOD'5l  L L LOOD'8u     OOD))MGTa>>D4a&#*;<<D$&&GT7###{ 
6i^**,, 	 	E% $$&&'*;;;c




^**,, 	6 	6E!!W%666ej%"2"2"4"4555	6 	6r   __main__r   )r   r   )r   r
   )r&   
__future__r   r   r   r   collectionsr   r   r   ImportErrorflake8.utilr   objectr   r)   r5   rT   r   r   r   r   r   r   r   r'   r   r   <module>r      s   
 & % % % % %  



  # # # # # #2JJJ$$$$$$$ 2 2 211111111112 # # # # # # # #8
 
 
 
 
v 
 
 
) ) ) ) ) ) ) )>C C C C CZ C C CL*C *C *C *C *CF *C *C *CZ   &F F F F  "6 6 6 6< zD!"" s   
' 77