ó
'![c           @  s3  d  Z  d d l m Z d d l Z d d l m Z d d l 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 d
 e f d „  ƒ  YZ d „  Z d e f d „  ƒ  YZ i d d 6Z d „  Z d e e f d „  ƒ  YZ d „  Z d d „ Z d d „ Z e d k r/e ƒ  n  d S(   sG   a similarities / code duplication command line tool and pylint checker
iÿÿÿÿ(   t   print_functionN(   t   defaultdict(   t   zip(   t   decoding_stream(   t   IRawChecker(   t   BaseCheckert   table_lines_from_stats(   t   Tablet   Similarc           B  s\   e  Z d  Z d e e e d „ Z d	 d „ Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z RS(
   s,   finds copy-pasted lines of code in a projecti   c         C  s1   | |  _  | |  _ | |  _ | |  _ g  |  _ d  S(   N(   t	   min_linest   ignore_commentst   ignore_docstringst   ignore_importst   linesets(   t   selfR	   R
   R   R   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   __init__#   s
    				c         C  st   | d k r | j } n t | | ƒ j } y2 |  j j t | | ƒ  |  j |  j |  j ƒ ƒ Wn t	 k
 ro n Xd S(   s(   append a file to search for similaritiesN(
   t   Nonet	   readlinesR   R   t   appendt   LineSetR
   R   R   t   UnicodeDecodeError(   R   t   streamidt   streamt   encodingR   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   append_stream+   s    c         C  s   |  j  |  j ƒ  ƒ d S(   s<   start looking for similarities and display results on stdoutN(   t   _display_simst   _compute_sims(   R   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   run:   s    c         C  s"  t  t ƒ } x± |  j ƒ  D]£ \ } } } } } | | } x | D]T } | | f | k si | | f | k r? | j | | f ƒ | j | | f ƒ Pq? q? W| j t | | f | | f g ƒ ƒ q Wg  }	 xA t j | ƒ D]0 \ } }
 x! |
 D] } |	 j | | f ƒ qé WqÖ W|	 j ƒ  |	 j	 ƒ  |	 S(   s&   compute similarities in appended files(
   R   t   listt
   _iter_simst   addR   t   sett   sixt	   iteritemst   sortt   reverse(   R   t   no_duplicatest   numt   lineset1t   idx1t   lineset2t   idx2t	   duplicatet   couplest   simst	   ensembles(    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyR   >   s     "
$)

c   	      C  s  d } x¸ | D]° \ } } t  ƒ  t  | d t | ƒ d ƒ t | ƒ } x+ | D]# \ } } t  d | j | f ƒ qL Wx/ | j | | | !D] } t  d | j ƒ  ƒ qˆ W| | t | ƒ d 7} q Wt g  |  j D] } t | ƒ ^ qÎ ƒ } t  d | | | d | f ƒ d	 S(
   s'   display computed similarities on stdouti    s   similar lines int   filess   ==%s:%ss     i   s)   TOTAL lines=%s duplicates=%s percent=%.2fg      Y@N(   t   printt   lent   sortedt   namet   _real_linest   rstript   sumR   (	   R   R,   t   nb_lignes_dupliqueesR%   R+   t   linesett   idxt   linet   nb_total_lignes(    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyR   R   s    (c         c  sS  | j  } | j  } | j } d } |  j } x"| t | ƒ k  rNd } d }	 xó | | | ƒ D]á }
 d } xÒ t t | | ƒ | |
 ƒ ƒ ƒ D]s \ }	 \ \ } } \ } } | | k rê | | k r× |	 | | | |
 f Vn  t | |	 ƒ } Pn  | rŠ | d 7} qŠ qŠ W|	 d 7}	 | | k r.|	 | | | |
 f Vn  t | |	 ƒ } q\ W| | 7} q- Wd S(   s+   find similarities in the two given linesetsi    i   N(   t   enumerate_strippedt   findR	   R0   t	   enumerateR   t   max(   R   R&   R(   t   lines1t   lines2R<   t   index1R	   t   skipR%   t   index2t	   non_blankt   _t   line1t   line2(    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   _find_commond   s0    				:
c         c  sf   x_ t  |  j d  ƒ D]J \ } } x; |  j | d D]( } x |  j | | ƒ D] } | VqK Wq2 Wq Wd S(   sW   iterate on similarities among all files, by making a cartesian
        product
        iÿÿÿÿi   N(   R=   R   RH   (   R   R8   R7   R(   t   sim(    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyR      s     N(   t   __name__t
   __module__t   __doc__t   FalseR   R   R   R   R   R   RH   R   (    (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyR       s   				c         C  sû   g  } d
 } xè |  D]à } | j ƒ  } | r‘ | rg | j d ƒ sP | j d ƒ rg | d  } | d } n  | r‘ | j | ƒ r… d
 } n  d } q‘ n  | rÁ | j d ƒ sµ | j d ƒ rÁ d } qÁ n  | ræ | j d d ƒ d	 j ƒ  } n  | j | ƒ q W| S(   s\   return lines with leading/trailing whitespace and any ignored code
    features removed
    s   """s   '''i   t    s   import s   from t   #i   i    N(   R   t   stript
   startswitht   endswitht   splitR   (   t   linesR
   R   R   t   strippedlinest	   docstringR9   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   stripped_linesŠ   s(    
	R   c           B  sk   e  Z d  Z e e e d „ Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d d „ Z
 d	 „  Z d
 „  Z RS(   s7   Holds and indexes all the lines of a single source filec         C  s=   | |  _  | |  _ t | | | | ƒ |  _ |  j ƒ  |  _ d  S(   N(   R2   R3   RW   t   _stripped_linest	   _mk_indext   _index(   R   R2   RT   R
   R   R   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyR   ©   s    			c         C  s   d |  j  S(   Ns   <Lineset for %s>(   R2   (   R   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   __str__²   s    c         C  s   t  |  j ƒ S(   N(   R0   R3   (   R   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   __len__µ   s    c         C  s   |  j  | S(   N(   RX   (   R   t   index(    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   __getitem__¸   s    c         C  s   |  j  | j  k  S(   N(   R2   (   R   t   other(    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   __lt__»   s    c         C  s
   t  |  ƒ S(   N(   t   id(   R   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   __hash__¾   s    i    c         c  sO   | } | r |  j  | } n	 |  j  } x# | D] } | | f V| d 7} q, Wd S(   sg   return an iterator on stripped lines, starting from a given index
        if specified, else 0
        i   N(   RX   (   R   t   start_atR8   RT   R9   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyR;   Á   s    	c         C  s   |  j  j | d ƒ S(   s7   return positions of the given stripped line in this set(    (   RZ   t   get(   R   t   stripped_line(    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyR<   Ï   s    c         C  sJ   t  t ƒ } x7 t |  j ƒ D]& \ } } | r | | j | ƒ q q W| S(   s   create the index for this set(   R   R   R=   RX   R   (   R   R]   t   line_noR9   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyRY   Ó   s
    (   RJ   RK   RL   RM   R   R[   R\   R^   R`   Rb   R;   R<   RY   (    (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyR   §   s   						s   Similar lines in %s files
%ss   duplicate-codesÁ   Indicates that a set of similar lines has been detected                   among multiple file. This usually means that the code should                   be refactored to avoid this duplication.t   R0801c      
   C  sT   d d d d g } | t  | | d ƒ 7} |  j t d | d d	 d
 d d d ƒ ƒ d S(   s/   make a layout with some stats about duplicationRN   t   nowt   previoust
   differencet   nb_duplicated_linest   percent_duplicated_linest   childrent   colsi   t   rheadersi   t   cheadersN(   Rk   Rl   (   R   R   R   (   t   sectt   statst	   old_statsRT   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   report_similaritiesâ   s
     
t   SimilarCheckerc           B  s  e  Z d  Z e f Z d Z e Z d i d d 6d d 6d d 6d	 d
 6f d i e d 6d d 6d d 6d d
 6f d i e d 6d d 6d d 6d d
 6f d i e	 d 6d d 6d d 6d d
 6f f Z
 d d e f f Z d d „ Z d d d „ Z d „  Z d „  Z d „  Z RS(   s£   checks for similarities and duplicated code. This computation may be
    memory / CPU intensive, so you should disable it if you experiment some
    problems.
    t   similaritiess   min-similarity-linesi   t   defaultt   intt   types   <int>t   metavars%   Minimum lines number of a similarity.t   helps   ignore-commentst   yns   <y or n>s,   Ignore comments when computing similarities.s   ignore-docstringss.   Ignore docstrings when computing similarities.s   ignore-importss+   Ignore imports when computing similarities.t   RP0801t   Duplicationc         C  s<   t  j |  | ƒ t j |  d d d t d t ƒd  |  _ d  S(   NR	   i   R
   R   (   R   R   R   t   TrueR   Rr   (   R   t   linter(    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyR     s    c         C  s•   t  j |  | | | | ƒ | d k r7 |  j j |  _ nZ | d k rU |  j j |  _ n< | d k rs |  j j |  _ n | d k r‘ |  j j |  _ n  d S(   s   method called to set an option (registered in the options list)

        overridden to report options setting to Similar
        s   min-similarity-liness   ignore-commentss   ignore-docstringss   ignore-importsN(   R   t
   set_optiont   configt   min_similarity_linesR	   R
   R   R   (   R   t   optnamet   valuet   actiont   optdict(    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyR     s    c         C  s+   g  |  _  |  j j d d d d ƒ |  _ d S(   s<   init the checkers: reset linesets and statistics informationRk   i    Rl   N(   R   R€   t	   add_statsRr   (   R   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   open!  s    	c         C  s5   | j  ƒ  # } |  j |  j j | | j ƒ Wd QXd S(   s   process a module

        the module's content is accessible via the stream object

        stream must implement the readlines method
        N(   R   R   R€   t   current_namet   file_encoding(   R   t   nodeR   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   process_module'  s    c   
      C  s  t  d „  |  j Dƒ ƒ } d } |  j } xÍ |  j ƒ  D]¿ \ } } g  } x. | D]& \ } } | j d | j | f ƒ qN W| j ƒ  x/ | j | | | !D] }	 | j |	 j ƒ  ƒ q— W|  j	 d d t
 | ƒ d j | ƒ f ƒ| | t
 | ƒ d 7} q5 W| | d <| o| d	 | | d
 <d S(   sA   compute and display similarities on closing (i.e. end of parsing)c         s  s   |  ] } t  | ƒ Vq d  S(   N(   R0   (   t   .0R7   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pys	   <genexpr>5  s    i    s   ==%s:%sRg   t   argss   
i   Rk   g      Y@Rl   N(   R5   R   Rr   R   R   R2   R"   R3   R4   t   add_messageR0   t   join(
   R   t   totalt
   duplicatedRr   R%   R+   t   msgR7   R8   R9   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   close3  s    	
(
N(   RJ   RK   RL   R   t   __implements__R2   t   MSGSt   msgsR   RM   t   optionsRt   t   reportsR   R   R   R‰   R   R•   (    (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyRu   ì   s,   	


		c         C  s   |  j  t |  ƒ ƒ d S(   s.   required method to auto register this checker N(   t   register_checkerRu   (   R€   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   registerF  s    i    c         C  s,   t  d ƒ t  ƒ  t  d ƒ t j |  ƒ d S(   s&   display command line usage informations*   finds copy pasted blocks in a set of filess~   Usage: symilar [-d|--duplicates min_duplicated_lines] [-i|--ignore-comments] [--ignore-docstrings] [--ignore-imports] file1...N(   R/   t   syst   exit(   t   status(    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   usageJ  s
    
c         C  sh  |  d k r t j d }  n  d d l m } d } d } d
 } t } t } t } | |  | | ƒ \ } }	 x„ | D]| \ }
 } |
 d k r– t | ƒ } qo |
 d k r¬ t ƒ  qo |
 d k rÁ t } qo |
 d k rÖ t } qo |
 d k ro t } qo qo W|	 st d ƒ n  t | | | | ƒ } x3 |	 D]+ } t	 | ƒ  } | j
 | | ƒ Wd QXqW| j ƒ  t j d ƒ d S(   s$   standalone command line access pointi   iÿÿÿÿ(   t   getoptt   hdiR{   s   duplicates=s   ignore-commentss   ignore-importss   ignore-docstringsi   s   -ds   --duplicatess   -hs   --helps   -is   --ignore-commentss   --ignore-docstringss   --ignore-importsNi    (   R{   s   duplicates=s   ignore-commentss   ignore-importss   ignore-docstrings(   s   -ds   --duplicates(   s   -hs   --help(   s   -is   --ignore-comments(   s   --ignore-docstrings(   s   --ignore-imports(   R   R   t   argvR¡   RM   Rx   R    R   R   R‰   R   R   Rž   (   R£   R¡   t   s_optst   l_optsR	   R
   R   R   t   optsR   t   optt   valRI   t   filenameR   (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   RunR  s<     
		
t   __main__(   s   Similar lines in %s files
%ss   duplicate-codesÁ   Indicates that a set of similar lines has been detected                   among multiple file. This usually means that the code should                   be refactored to avoid this duplication.(   RL   t
   __future__R    R   t   collectionsR   R    t	   six.movesR   t   pylint.utilsR   t   pylint.interfacesR   t   pylint.checkersR   R   t   pylint.reporters.ureports.nodesR   t   objectR   RW   R   R—   Rt   Ru   Rœ   R    R   Rª   RJ   (    (    (    s6   lib/python2.7/site-packages/pylint/checkers/similar.pyt   <module>   s,   j	5 
	
Z	!