
"Ic           @   s(  d  Z  d Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k l Z d d k	 l
 Z
 d d k l Z d d k l Z d d	 k l Z d d
 k l Z d d k l Z d d k l Z e d  Z d   Z d   Z d   Z d e f d     YZ d e f d     YZ d   Z d S(   s   Refactoring framework.

Used as a main program, this can refactor any number of files and/or
recursively descend down directories.  Imported as a module, this
provides infrastructure to write your own refactoring tool.
s#   Guido van Rossum <guido@python.org>iN(   t   defaultdict(   t   chaini   (   t   driver(   t   tokenize(   t   pytree(   t   patcomp(   t   fixes(   t   pygramc         C   s   t  |  g  g  d g  } t i i | i  } g  } t i |  } | i   xX | D]P } | i d  o: | i d  o* | o | d } n | i	 | d   qS qS W| S(   sE   Return a sorted list of all available fix names in the given package.t   *t   fix_s   .pyi   i(
   t
   __import__t   ost   patht   dirnamet   __file__t   listdirt   sortt
   startswitht   endswitht   append(   t	   fixer_pkgt   remove_prefixt   pkgt	   fixer_dirt	   fix_namest   namest   name(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyt   get_all_fix_names"   s    
  c         C   s   t  |  t i t i f  o t |  i g  St  |  t i  o& |  i o t |  i  St d g  St  |  t i
  oF t   } x5 |  i D]* } x! | D] } | i t |   q Wq W| St d |    d S(   sf    Accepts a pytree Pattern Node and returns a set
        of the pattern types which will match first. s$   Oh no! I don't understand pattern %sN(   t
   isinstanceR   t   NodePatternt   LeafPatternt   sett   typet   NegatedPatternt   contentt   get_head_typest   Nonet   WildcardPatternt   updatet	   Exception(   t   patt   rt   pt   x(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR#   0   s    
	
  c         C   sn   t  t  } x[ |  D]S } | i p | d i |  q n x( t | i  D] } | | i |  qK Wq W| S(   s^    Accepts a list of fixers and returns a dictionary
        of head node type --> fixer list.  N(   R    t   listt   patternR$   R   R#   (   t
   fixer_listt
   head_nodest   fixert   t(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyt   get_headnode_dictI   s     
 c         C   s0   g  } t  |  t  D] } | |  d | q ~ S(   sN   
    Return the fully qualified names for fixers in the package pkg_name.
    t   .(   R   t   False(   t   pkg_namet   _[1]t   fix_name(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyt   get_fixers_from_packageU   s    t
   FixerErrorc           B   s   e  Z d  Z RS(   s   A fixer could not be loaded.(   t   __name__t
   __module__t   __doc__(    (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR9   ]   s   t   RefactoringToolc           B   s  e  Z h e d  6Z d Z d Z d d d  Z d   Z d   Z	 d   Z
 d   Z d   Z e e d	  Z e e d
  Z e e d  Z d   Z e d  Z d   Z d   Z d e d  Z d d  Z d Z d Z d   Z d   Z d   Z d   Z d   Z d   Z RS(   t   print_functiont   FixR	   c         C   s  | |  _  | p g  |  _ |  i i   |  _ | d j	 o |  i i |  n g  |  _ t i	 d  |  _
 g  |  _ t |  _ |  i d o t i i d =n t i t i d t i d |  i
 |  _ |  i   \ |  _ |  _ t |  i  |  _ t |  i  |  _ g  |  _ d S(   s   Initializer.

        Args:
            fixer_names: a list of fixers to import
            options: an dict with configuration.
            explicit: a list of fixers to run even if they are explicit.
        R=   R>   t   printt   convertt   loggerN(   t   fixerst   explicitt   _default_optionst   copyt   optionsR$   R&   t   errorst   loggingt	   getLoggerRB   t	   fixer_logR4   t   wroteR   t   python_grammart   keywordsR   t   DriverR   RA   t
   get_fixerst	   pre_ordert
   post_orderR2   t   files(   t   selft   fixer_namesRG   RD   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyt   __init__h   s$    					c      
   C   s  g  } g  } x|  i  D]} t | h  h  d g  } | i d d  d } | i |  i  o | t |  i  } n | i d  } |  i d i g  } | D] } | | i	   q ~  }	 y t
 | |	  }
 Wn) t j
 o t d | |	 f   n X|
 |  i |  i  } | i o7 |  i t j	 o' | |  i j o |  i d |  q n |  i d	 |  | i d
 j o | i |  q | i d j o | i |  q t d | i   q Wt i d  } | i d |  | i d |  | | f S(   s  Inspects the options to load the requested patterns and handlers.

        Returns:
          (pre_order, post_order), where pre_order is the list of fixers that
          want a pre-order AST traversal, and post_order is the list that want
          post-order traversal.
        R   R3   i   it   _t    s   Can't find %s.%ss   Skipping implicit fixer: %ss   Adding transformation: %st   pret   posts   Illegal fixer order: %rt	   run_ordert   key(   RC   R
   t   rsplitR   t   FILE_PREFIXt   lent   splitt   CLASS_PREFIXt   joint   titlet   getattrt   AttributeErrorR9   RG   RK   RD   t   Truet   log_messaget	   log_debugt   orderR   t   operatort
   attrgetterR   (   RT   t   pre_order_fixerst   post_order_fixerst   fix_mod_patht   modR7   t   partsR6   R*   t
   class_namet	   fix_classR0   t   key_func(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyRP      s:    
 7c         O   s     d S(   s   Called when an error occurs.N(    (   RT   t   msgt   argst   kwds(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyt	   log_error   s    c         G   s)   | o | | } n |  i  i |  d S(   s   Hook to log a message.N(   RB   t   info(   RT   Rt   Ru   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyRg      s    c         G   s)   | o | | } n |  i  i |  d  S(   N(   RB   t   debug(   RT   Rt   Ru   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyRh      s    c         C   s   d S(   s0   Called with lines of output to give to the user.N(    (   RT   t   lines(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyt   print_output   s    c         C   sR   xK | D]C } t  i i |  o |  i | | |  q |  i | | |  q Wd S(   s)   Refactor a list of files and directories.N(   R   R   t   isdirt   refactor_dirt   refactor_file(   RT   t   itemst   writet   doctests_onlyt   dir_or_file(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyt   refactor   s
     c         C   s   x t  i |  D] \ } } } |  i d |  | i   | i   x[ | D]S } | i d  o< | i d  o, t  i i | |  } |  i | | |  qJ qJ Wg  }	 | D]! }
 |
 i d  p |	 |
 q q ~	 | (q Wd S(   s   Descends down a directory and refactor every Python file found.

        Python files are assumed to have a .py extension.

        Files and subdirectories starting with '.' are skipped.
        s   Descending into %sR3   t   pyN(	   R   t   walkRh   R   R   R   R   Rb   R~   (   RT   t   dir_nameR   R   t   dirpatht   dirnamest	   filenamesR   t   fullnameR6   t   dn(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR}      s     

 !c   	      C   s   y t  |  } Wn) t j
 o } |  i d | |  d SXz | i   d } Wd | i   X| o` |  i d |  |  i | |  } | | j o |  i | | | d | q|  i d |  nX |  i | |  } | o. | i	 o$ |  i t
 |  d  | d | n |  i d |  d S(	   s   Refactors a file.s   Can't open %s: %sNs   
s   Refactoring doctests in %sR   s   No doctest changes in %sis   No changes in %s(   t   opent   IOErrorRw   t   readt   closeRh   t   refactor_docstringt   processed_filet   refactor_stringt   was_changedt   str(	   RT   t   filenameR   R   t   ft   errt   inputt   outputt   tree(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR~      s$    $c         C   sr   y |  i  i | d  } Wn2 t j
 o& } |  i d | | i i |  d SX|  i d |  |  i | |  | S(   sF  Refactor a given input string.

        Args:
            data: a string holding the code to be refactored.
            name: a human-readable name for use in error/log messages.

        Returns:
            An AST corresponding to the refactored input stream; None if
            there were errors during the parse.
        i   s   Can't parse %s: %s: %sNs   Refactoring %s(   R   t   parse_stringR'   Rw   t	   __class__R:   Rh   t   refactor_tree(   RT   t   dataR   R   R   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR      s    	c         C   s   t  i i   } | oT |  i d  |  i | d  } | | j o |  i | d |  q |  i d  nN |  i | d  } | o' | i o |  i t |  d |  n |  i d  d  S(   Ns   Refactoring doctests in stdins   <stdin>s   No doctest changes in stdins   No changes in stdin(	   t   syst   stdinR   Rh   R   R   R   R   R   (   RT   R   R   R   R   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyt   refactor_stdin	  s    c         C   s   t  t  |  i i     t  |  i i      } x | D] } | i | |  q4 W|  i |  i | i    |  i |  i | i    x | D] } | i | |  q W| i S(   sA  Refactors a parse tree (modifying the tree in place).

        Args:
            tree: a pytree.Node instance representing the root of the tree
                  to be refactored.
            name: a human-readable name for this tree.

        Returns:
            True if the tree was modified, False otherwise.
        (   R   RQ   t   valuesRR   t
   start_treet   traverse_byt   finish_treeR   (   RT   R   R   t
   all_fixersR0   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR     s      c         C   s   | p d Sx | D] } x | | i  | d D]| } | i |  } | o` | i | |  } | d j	 o= | | j p t |  t |  j o | i |  | } q q/ q/ Wq Wd S(   s  Traverse an AST, applying a set of fixers to each node.

        This is a helper method for refactor_tree().

        Args:
            fixers: a list of fixer instances.
            traversal: a generator that yields AST nodes.

        Returns:
            None
        N(   R    R$   t   matcht	   transformR   t   replace(   RT   RC   t	   traversalt   nodeR0   t   resultst   new(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR   3  s      c         C   s   |  i  i |  | d j oa y t | d  } Wn) t j
 o } |  i d | |  d SXz | i   } Wd | i   Xn | | j o |  i d |  d S|  i	 t
 | | |   | o |  i | | |  n |  i d |  d S(   sP   
        Called when a file has been refactored, and there are changes.
        R)   s   Can't read %s: %sNs   No changes to %ss   Not writing changes to %s(   RS   R   R$   R   R   Rw   R   R   Rh   R{   t
   diff_textst
   write_file(   RT   t   new_textR   t   old_textR   R   R   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR   K  s"    c         C   sO  | d } t  i i |  o@ y t  i |  Wq] t  i j
 o } |  i d |  q] Xn y t  i | |  Wn+ t  i j
 o } |  i d | |  n Xy t | d  } Wn, t  i j
 o } |  i d | |  d SXzC y | i	 |  Wn+ t  i j
 o } |  i d | |  n XWd | i
   X|  i d |  t |  _ d S(	   s   Writes a string to a file.

        It first shows a unified diff between the old text and the new text, and
        then rewrites the file; the latter is only done if the write option is
        set.
        s   .baks   Can't remove backup %ss   Can't rename %s to %st   ws   Can't create %s: %sNs   Can't write %s: %ss   Wrote changes to %s(   R   R   t   lexistst   removet   errorRg   t   renameR   Rw   R   R   Rh   Rf   RL   (   RT   R   R   R   t   backupR   R   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR   c  s.    
s   >>> s   ... c   
      C   s  g  } d } d } d } d } x5| i t  D]$} | d 7} | i   i |  i  o_ | d j	 o# | i |  i | | | |   n | } | g } | i |  i  }	 | |	  } q. | d j	 oF | i | |  i	  p | | |  i	 i
   d j o | i |  q. | d j	 o# | i |  i | | | |   n d } d } | i |  q. W| d j	 o# | i |  i | | | |   n d i |  S(   s  Refactors a docstring, looking for doctests.

        This returns a modified version of the input string.  It looks
        for doctests, which start with a ">>>" prompt, and may be
        continued with "..." prompts, as long as the "..." is indented
        the same as the ">>>".

        (Unfortunately we can't use the doctest module's parser,
        since, like most parsers, it is not geared towards preserving
        the original source.)
        i    i   s   
RX   N(   R$   t
   splitlinesRf   t   lstripR   t   PS1t   extendt   refactor_doctestt   findt   PS2t   rstripR   Rb   (
   RT   R   R   t   resultt   blockt   block_linenot   indentt   linenot   linet   i(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR     s<     
	c         C   sb  y |  i  | | |  } Wny t j
 om } |  i i t i  o. x+ | D] } |  i d | i d   qI Wn |  i d | | | i	 i
 |  | SX|  i | |  o t |  i t  } | | d  | | d }	 } | d i d  p | d c d 7<n | |  i | i d  g } | o4 | g  }
 | D] } |
 | |  i | q4~
 7} q^n | S(   s   Refactors one doctest.

        A doctest is given as a block of lines, the first of which starts
        with ">>>" (possibly indented), while the remaining lines start
        with "..." (identically indented).

        s
   Source: %ss   
s+   Can't parse docstring in %s line %s: %s: %si   ii    (   t   parse_blockR'   t   logt   isEnabledForRI   t   DEBUGRh   R   Rw   R   R:   R   R   R   Rf   R   R   t   popR   (   RT   R   R   R   R   R   R   R   R   t   clippedR6   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR     s&     !	8c      	   C   s'  |  i  o
 d } n d } |  i p |  i d |  n2 |  i d |  x |  i D] } |  i |  qR W|  i o2 |  i d  x" |  i D] } |  i |  q Wn |  i ot t |  i  d j o |  i d  n |  i d t |  i   x1 |  i D]" \ } } } |  i | | |  q Wn d  S(	   Nt   weres
   need to bes   No files %s modified.s   Files that %s modified:s$   Warnings/messages while refactoring:i   s   There was 1 error:s   There were %d errors:(   RL   RS   Rg   RK   RH   R_   (   RT   R   t   filet   messageRt   Ru   Rv   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyt	   summarize  s*    



 

 

 c         C   s   |  i  i |  i | | |   S(   s   Parses a block into a tree.

        This is necessary to get correct line number / offset information
        in the parser diagnostics and embedded into the parse tree.
        (   R   t   parse_tokenst	   wrap_toks(   RT   R   R   R   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR     s    c         c   s   t  i |  i | |  i  } xe | D]] \ } } \ } } \ }	 }
 } | | d 7} |	 | d 7}	 | | | | f |	 |
 f | f Vq% Wd S(   s;   Wraps a tokenize stream to systematically modify start/end.i   N(   R   t   generate_tokenst	   gen_linest   next(   RT   R   R   R   t   tokensR    t   valuet   line0t   col0t   line1t   col1t	   line_text(    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR     s     !c         c   s   | |  i  } | |  i } | } xm | D]e } | i |  o | t |  Vn7 | | i   d j o	 d Vn t d | | f   | } q' Wx t o	 d Vq Wd S(   s   Generates lines as expected by tokenize from a list of lines.

        This strips the first len(indent + self.PS1) characters off each line.
        s   
s   line=%r, prefix=%rRX   N(   R   R   R   R_   R   t   AssertionErrorRf   (   RT   R   R   t   prefix1t   prefix2t   prefixR   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR     s     	
 N(   R:   R;   R4   RE   Ra   R^   R$   RV   RP   Rw   Rg   Rh   R{   R   R}   R~   R   R   R   R   R   R   R   R   R   R   R   R   R   R   (    (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR=   a   s4   	(							 	+				c      	   C   s:   |  i    }  | i    } t i |  | | | d d d d S(   s%   Return a unified diff of two strings.s
   (original)s   (refactored)t   linetermRX   (   R   t   difflibt   unified_diff(   t   at   bR   (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyR     s
    	(   R<   t
   __author__R   R   R   RI   Rj   t   collectionsR    t	   itertoolsR   t   pgen2R   R   RX   R   R   R   R   Rf   R   R#   R2   R8   R'   R9   t   objectR=   R   (    (    (    s-   /mit/python/lib/python2.6/lib2to3/refactor.pyt   <module>
   s,   			 