B
    )zf)                 @   s  d Z ddlmZ ddlZddlZddlZddlmZ yddlZddlm	Z	 W n$ e
k
rp   ddlmZm	Z	 Y nX d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dddZdddZdd Zd ddZedkreejdd  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.6.1c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )
ASTVisitorz'Performs a depth-first walk of the AST.c             C   s   d | _ i | _d S )N)node_cache)self r
   I/home/ankuromar296_gmail_com/.local/lib/python3.7/site-packages/mccabe.py__init__   s    zASTVisitor.__init__c             G   s&   x t |D ]}| j|f|  q
W d S )N)r   dispatch)r	   r   argschildr
   r
   r   default   s    zASTVisitor.defaultc             G   sR   || _ |j}| j|}|d krD|j}t| jd| | j}|| j|< ||f| S )Nvisit)r   	__class__r   get__name__getattrvisitorr   )r	   r   r   klassmethZ	classNamer
   r
   r   r   !   s    
zASTVisitor.dispatchc             G   s"   || _ | j|_| j|f|  dS )z&Do preorder walk of tree using visitorN)r   r   r   )r	   treer   r   r
   r
   r   preorder+   s    zASTVisitor.preorderN)r   
__module____qualname____doc__r   r   r   r   r
   r
   r
   r   r      s
   
r   c               @   s&   e Zd Zd	ddZdd Zdd ZdS )
PathNodecirclec             C   s   || _ || _d S )N)namelook)r	   r    r!   r
   r
   r   r   3   s    zPathNode.__init__c             C   s   t d| j| j|  f  d S )Nznode [shape=%s,label="%s"] %d;)printr!   r    dot_id)r	   r
   r
   r   to_dot7   s    zPathNode.to_dotc             C   s   t | S )N)id)r	   r
   r
   r   r#   ;   s    zPathNode.dot_idN)r   )r   r   r   r   r$   r#   r
   r
   r
   r   r   2   s   
r   c               @   s.   e Zd ZdddZdd Zdd Zdd	 Zd
S )	PathGraphr   c             C   s&   || _ || _|| _|| _tt| _d S )N)r    entitylinenocolumnr   listnodes)r	   r    r'   r(   r)   r
   r
   r   r   @   s
    zPathGraph.__init__c             C   s   | j | | g | j |< d S )N)r+   append)r	   Zn1Zn2r
   r
   r   connectG   s    zPathGraph.connectc             C   sj   t d x| jD ]}|  qW x<| j D ].\}}x$|D ]}t d| | f  q:W q,W t d d S )Nz
subgraph {z	%s -- %s;})r"   r+   r$   itemsr#   )r	   r   Znextsnextr
   r
   r   r$   L   s    
 zPathGraph.to_dotc             C   s.   t dd | j D }t| j}|| d S )zG Return the McCabe complexity for the graph.
            V-E+2
        c             S   s   g | ]}t |qS r
   )len).0nr
   r
   r   
<listcomp>Y   s    z(PathGraph.complexity.<locals>.<listcomp>   )sumr+   valuesr1   )r	   Z	num_edgesZ	num_nodesr
   r
   r   
complexityU   s    
zPathGraph.complexityN)r   )r   r   r   r   r-   r$   r8   r
   r
   r
   r   r&   ?   s   
	r&   c                   s   e Zd ZdZ fddZdd Zdd Zdd	 ZeZd
d Z	dd Z
dd Z fddZdd Ze Z ZZdd ZdddZdd Zdd ZeZdd ZeZ  ZS ) PathGraphingAstVisitorz\ A visitor for a parsed Abstract Syntax Tree which finds executable
        statements.
    c                s&   t t|   d| _i | _|   d S )N )superr9   r   	classnamegraphsreset)r	   )r   r
   r   r   c   s    zPathGraphingAstVisitor.__init__c             C   s   d | _ d | _d S )N)graphtail)r	   r
   r
   r   r>   i   s    zPathGraphingAstVisitor.resetc             C   s   x|D ]}|  | qW d S )N)r   )r	   Z	node_listr   r
   r
   r   dispatch_listm   s    
z$PathGraphingAstVisitor.dispatch_listc             C   s   | j rd| j |jf }n|j}d|j|j|f }| jd k	r| |}|| _| |j t	ddd}| j
| j| | j
|| || _nNt|||j|j| _t	|}|| _| |j | j| jd| j |jf < |   d S )Nz%s%sz	%d:%d: %rr:   point)r!   )r<   r    r(   
col_offsetr?   appendPathNoder@   rA   bodyr   r-   r&   r=   r>   )r	   r   r'   r    pathnodebottomr
   r
   r   visitFunctionDefq   s$    

z'PathGraphingAstVisitor.visitFunctionDefc             C   s0   | j }|  j |jd 7  _ | |j || _ d S )N.)r<   r    rA   rE   )r	   r   Zold_classnamer
   r
   r   visitClassDef   s    z$PathGraphingAstVisitor.visitClassDefc             C   s,   | j s
d S t|}| j| j | || _ |S )N)r@   r   r?   r-   )r	   r    rF   r
   r
   r   rD      s    z%PathGraphingAstVisitor.appendPathNodec             C   s,   |j d krd}n|j }d| }| | d S )Nr   zStmt %d)r(   rD   )r	   r   r(   r    r
   r
   r   visitSimpleStatement   s
    
z+PathGraphingAstVisitor.visitSimpleStatementc                s2   t |tjr| | ntt| j|f|  d S )N)
isinstancer   stmtrK   r;   r9   r   )r	   r   r   )r   r
   r   r      s    zPathGraphingAstVisitor.defaultc             C   s   d|j  }| || d S )NzLoop %d)r(   	_subgraph)r	   r   r    r
   r
   r   	visitLoop   s    
z PathGraphingAstVisitor.visitLoopc             C   s   d|j  }| || d S )NzIf %d)r(   rN   )r	   r   r    r
   r
   r   visitIf   s    
zPathGraphingAstVisitor.visitIfr
   c             C   sp   | j dkrTt|||j|j| _ t|}| ||| | j | jd| j|f < |   n| 	|}| ||| dS )z?create the subgraphs representing any `if` and `for` statementsNz%s%s)
r?   r&   r(   rC   r   _subgraph_parser=   r<   r>   rD   )r	   r   r    extra_blocksrF   r
   r
   r   rN      s    


z PathGraphingAstVisitor._subgraphc             C   s   g }|| _ | |j || j  x*|D ]"}|| _ | |j || j  q(W |jrt|| _ | |j || j  n
|| |rtddd}x|D ]}| j|| qW || _ dS )z@parse the body and any `else` block of `if` and `for` statementsr:   rB   )r!   N)r@   rA   rE   r,   Zorelser   r?   r-   )r	   r   rF   rR   Z
loose_endsextrarG   ler
   r
   r   rQ      s$    


z&PathGraphingAstVisitor._subgraph_parsec             C   s    d|j  }| j|||jd d S )NzTryExcept %d)rR   )r(   rN   handlers)r	   r   r    r
   r
   r   visitTryExcept   s    
z%PathGraphingAstVisitor.visitTryExceptc             C   s$   d|j  }| | | |j d S )NzWith %d)r(   rD   rA   rE   )r	   r   r    r
   r
   r   	visitWith   s    

z PathGraphingAstVisitor.visitWith)r
   )r   r   r   r   r   r>   rA   rH   ZvisitAsyncFunctionDefrJ   rD   rK   r   rO   ZvisitAsyncForZvisitForZ
visitWhilerP   rN   rQ   rV   ZvisitTryrW   ZvisitAsyncWith__classcell__r
   r
   )r   r   r9   ^   s&   
r9   c               @   sL   e Zd ZdZdZeZdZdZdZ	dd Z
edd	 Zed
d Zdd ZdS )McCabeCheckerz%McCabe cyclomatic complexity checker.ZmccabeZC901zC901 %r is too complex (%d)c             C   s
   || _ d S )N)r   )r	   r   filenamer
   r
   r   r      s    zMcCabeChecker.__init__c             C   sb   d}dddddd}t |dd }t|trP|d	 |j|f| |jd
 n|j|f| d S )Nz--max-complexityrZ   storeintzMcCabe complexity thresholdTrue)r   actiontypehelpparse_from_configconfig_optionsrb   zmax-complexity)r   rL   r*   pop
add_optionrc   r,   )clsparserflagkwargsZconfig_optsr
   r
   r   add_options   s    

zMcCabeChecker.add_optionsc             C   s   t |j| _d S )N)r]   max_complexity)rf   optionsr
   r
   r   parse_options  s    zMcCabeChecker.parse_optionsc             c   sr   | j dk rd S t }|| j| xJ|j D ]<}| | j kr.| j|j| f }|j	|j
|t| fV  q.W d S )Nr   )rk   r9   r   r   r=   r7   r8   _error_tmplr'   r(   r)   r`   )r	   r   r?   textr
   r
   r   run  s    
zMcCabeChecker.runN)r   r   r   r   r    __version__version_codern   rk   r   classmethodrj   rm   rp   r
   r
   r
   r   rY      s   rY      stdinc       
      C   s   yt | |dtj}W n4 tk
rH   t d }tjd||f  dS X g }|t_	x2t||
 D ] \}}}}	|d|||f  qdW t|dkrdS td| t|S )Nexec   zUnable to parse %s: %s
r   z%s:%d:1: %s
)compiler   PyCF_ONLY_ASTSyntaxErrorsysexc_infostderrwriterY   rk   rp   r,   r1   r"   join)
code	thresholdr[   r   eZcomplxr(   offsetro   checkr
   r
   r   get_code_complexity  s    r   c          	   C   s,   t | d}| }W dQ R X t||| dS )z"Returns the complexity of a modulerUN)r[   )openreadr   )module_pathr   modr   r
   r
   r   get_module_complexity$  s    r   c             C   s   dt j  k rdk r6n nt| d
}| S Q R X ndt j  krLdk rn ny*t| d}t|j\}}W d Q R X W n6 ttt	fk
r   t| dd
}| S Q R X Y nX t| d|d
}| S Q R X d S )	N)r5      )   r   r   )   r   rbzlatin-1)encodingr)
r}   version_infor   r   tokenizedetect_encodingreadlineLookupErrorr|   UnicodeError)r[   fr   _r
   r
   r   _read+  s    r   c             C   s  | d krt jdd  } t }|jdddddd |jdd	d
dddd || \}}t|d }t||d dtj	}t
 }||| |jrtd x.|j D ] }|jr| |jkr|  qW td n2x0|j D ]"}| |jkrt|j|  qW d S )Nrx   z-dz--dotdotzoutput a graphviz dot file
store_true)destra   r_   z-mz--minr   zminimum complexity for outputr]   )r   ra   r`   r   r   rw   zgraph {r.   )r}   argvoptparseOptionParserre   
parse_argsr   rz   r   r{   r9   r   r   r"   r=   r7   r   r8   r$   r    )r   Zoparrl   r   r   r   r   r?   r
   r
   r   main<  s.    



r   __main__rx   )ru   rv   )ru   )N)r   
__future__r   r   r}   r   collectionsr   r   r   ImportErrorZflake8.utilrq   objectr   r   r&   r9   rY   r   r   r   r   r   r   r
   r
   r
   r   <module>   s.    -



