Ë
    #´˜jsk  ã                   ó   — d Z 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Zddl	m
Z
 ddlmZmZmZ ddlmZ ddlmZmZ dd	lmZ dd
„Z G d„ de«      Zd„ Zd„ Zd„ Zd„ Zd„ Z G d„ de«      Z G d„ de«      Z  G d„ de«      Z! G d„ de «      Z"y)zÛ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.
z#Guido van Rossum <guido@python.org>é    N)Úchainé   )ÚdriverÚtokenizeÚtoken)Ú	find_root)ÚpytreeÚpygram)Úbtm_matcherc                 óÌ   — t        | g g dg«      }g }t        j                  |j                  «      D ]0  \  }}}|j	                  d«      sŒ|r|dd }|j                  |«       Œ2 |S )zEReturn a sorted list of all available fix names in the given package.Ú*Úfix_é   N)Ú
__import__ÚpkgutilÚiter_modulesÚ__path__Ú
startswithÚappend)Ú	fixer_pkgÚremove_prefixÚpkgÚ	fix_namesÚfinderÚnameÚispkgs          ú"lib/python3.12/lib2to3/refactor.pyÚget_all_fix_namesr      sj   € ä
�Y  B¨¨Ó
.€CØ€IÜ&×3Ñ3°C·L±LÖAÑˆ��eØ�?‰?˜6Õ"ÙØ˜A˜B�x�Ø×Ñ˜TÕ"ð	  Bð
 Ðó    c                   ó   — e Zd Zy)Ú
_EveryNodeN©Ú__name__Ú
__module__Ú__qualname__© r   r   r!   r!   +   ó   „ Ør   r!   c                 óâ  — t        | t        j                  t        j                  f«      r| j                  €t
        ‚| j                  hS t        | t        j                  «      r'| j                  rt        | j                  «      S t
        ‚t        | t        j                  «      r>t        «       }| j                  D ]#  }|D ]  }|j                  t        |«      «       Œ Œ% |S t        d| z  «      ‚)zf Accepts a pytree Pattern Node and returns a set
        of the pattern types which will match first. z$Oh no! I don't understand pattern %s)Ú
isinstancer	   ÚNodePatternÚLeafPatternÚtyper!   ÚNegatedPatternÚcontentÚ_get_head_typesÚWildcardPatternÚsetÚupdateÚ	Exception)ÚpatÚrÚpÚxs       r   r/   r/   /   sÁ   € ô �#œ×*Ñ*¬F×,>Ñ,>Ð?Ô@ð �8‰8ÐÜÐØ—‘ˆzÐä�#”v×,Ñ,Ô-Ø�;Š;Ü" 3§;¡;Ó/Ð/ÜÐä�#”v×-Ñ-Ô.ä‹EˆØ—”ˆAÛ�Ø—‘œ¨Ó+Õ,ñ ð ð ˆä
Ð:¸SÑAÓ
BÐBr   c                 óX  — t        j                  t        «      }g }| D ]|  }|j                  r2	 t	        |j                  «      }|D ]  }||   j                  |«       Œ ŒA|j                  �||j                     j                  |«       Œl|j                  |«       Œ~ t        t        j                  j                  j                  «       t        j                  j                  «      D ]  }||   j                  |«       Œ t        |«      S # t        $ r |j                  |«       Y �Œ
w xY w)z^ Accepts a list of fixers and returns a dictionary
        of head node type --> fixer list.  )ÚcollectionsÚdefaultdictÚlistÚpatternr/   r   r!   Ú_accept_typer   r
   Úpython_grammarÚsymbol2numberÚvaluesÚtokensÚextendÚdict)Ú
fixer_listÚ
head_nodesÚeveryÚfixerÚheadsÚ	node_types         r   Ú_get_headnode_dictrJ   K   s  € ô ×(Ñ(¬Ó.€JØ€EÛˆØ�=Š=ð8Ü'¨¯©Ó6�ó "'�IØ˜yÑ)×0Ñ0°Õ7ñ "'ð ×!Ñ!Ð-Ø˜5×-Ñ-Ñ.×5Ñ5°eÕ<à—‘˜UÕ#ð ô œ6×0Ñ0×>Ñ>×EÑEÓGÜ!×0Ñ0×7Ñ7ö9ˆ	à�9Ñ×$Ñ$ UÕ+ð9ô �
ÓÐøô ò $Ø—‘˜U×#ð$ús   ®DÄD)Ä(D)c                 óL   — t        | d«      D �cg c]
  }| dz   |z   ‘Œ c}S c c}w )zN
    Return the fully qualified names for fixers in the package pkg_name.
    FÚ.)r   )Úpkg_nameÚfix_names     r   Úget_fixers_from_packagerO   d   s=   € ô
 .¨h¸Ô>ó@Ù>�ð �s‰N˜XÓ%Ø>ñ@ð @ùò @s   �!c                 ó   — | S ©Nr&   )Úobjs    r   Ú	_identityrS   k   s   € Ø€Jr   c                 ó|  ‡— d}t        j                  t        j                  | «      j                  «      Šˆfd„}t        t        j                  t         j                  t        j                  h«      }t        «       }	 	  |«       \  }}||v rŒ|t        j                  k(  r|rnöd}nñ|t        j                  k(  rÝ|dk(  rØ |«       \  }}|t        j                  k7  s|dk7  rn¸ |«       \  }}|t        j                  k7  s|dk7  rn• |«       \  }}|t        j                  k(  r|dk(  r
 |«       \  }}|t        j                  k(  rT|j                  |«        |«       \  }}|t        j                  k7  s|dk7  rn  |«       \  }}|t        j                  k(  rŒRnn�Œt        |«      S # t        $ r Y t        |«      S w xY w)	NFc                  ó.   •— t        ‰«      } | d   | d   fS )Nr   r   )Únext)ÚtokÚgens    €r   Úadvancez(_detect_future_features.<locals>.advancer   s   ø€ Ü�3‹iˆØ�1‰v�s˜1‘vˆ~Ðr   TÚfromÚ
__future__ÚimportÚ(Ú,)r   Úgenerate_tokensÚioÚStringIOÚreadlineÚ	frozensetr   ÚNEWLINEÚNLÚCOMMENTr1   ÚSTRINGÚNAMEÚOPÚaddÚStopIteration)ÚsourceÚhave_docstringrY   ÚignoreÚfeaturesÚtpÚvaluerX   s          @r   Ú_detect_future_featuresrr   o   s‡  ø€ Ø€NÜ
×
"Ñ
"¤2§;¡;¨vÓ#6×#?Ñ#?Ó
@€Côô œŸ™¤x§{¡{´E·M±MÐBÓC€FÜ‹u€HðØÙ›	‰IˆB�Ø�V‰|ØØ”u—|‘|Ò#Ù!ØØ!%‘Ø”u—z‘zÒ! e¨v¢oÙ#›I‘	��EØœŸ™Ò# u°Ò'<ØÙ#›I‘	��EØœŸ™Ò# u°Ò'8ØÙ#›I‘	��EØœŸ™’> e¨s¢lÙ '£	‘I�B˜ØœEŸJ™JÒ&Ø—L‘L Ô'Ù '£	‘I�B˜ØœUŸX™X’~¨°#ªØÙ '£	‘I�B˜ð œEŸJ™JÔ&ð ñ3 ô8 �XÓÐøô ò ØÜ�XÓÐðús   Á>DF% ÆF% Æ%	F;Æ:F;c                   ó   — e Zd ZdZy)Ú
FixerErrorzA fixer could not be loaded.N)r#   r$   r%   Ú__doc__r&   r   r   rt   rt   —   s   „ Ú&r   rt   c                   ó¾   — e Zd ZddddœZdZdZdd„Zd„ Zd„ Zd	„ Z	d
„ Z
d„ Zdd„Zdd„Zd„ Zdd„Zd„ Zd d„Zd„ Zd„ Z	 	 d!d„Zd"d„ZdZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)#ÚRefactoringToolF)Úprint_functionÚexec_functionÚwrite_unchanged_filesÚFixr   Nc                 óÜ  — || _         |xs g | _        | j                  j                  «       | _        |�| j                  j                  |«       t        j                  j                  «       | _        | j                  d   r| j                  j                  d= n&| j                  d   r| j                  j                  d= | j                  j                  d«      | _        g | _        t        j                  d«      | _        g | _        d| _        t%        j&                  | j                  t(        j*                  | j                  ¬	«      | _        | j-                  «       \  | _        | _        g | _        t5        j6                  «       | _        g | _        g | _        t?        | j0                  | j.                  «      D ]~  }|j@                  r| j8                  jC                  |«       Œ+|| j.                  v r| j:                  jE                  |«       ŒU|| j0                  v sŒd| j<                  jE                  |«       Œ€ tG        | j:                  «      | _$        tG        | j<                  «      | _%        y)
zÑInitializer.

        Args:
            fixer_names: a list of fixers to import
            options: a dict with configuration.
            explicit: a list of fixers to run even if they are explicit.
        Nrx   Úprintry   Úexecrz   rw   F)ÚconvertÚlogger)&ÚfixersÚexplicitÚ_default_optionsÚcopyÚoptionsr2   r
   r>   ÚgrammarÚkeywordsÚgetrz   ÚerrorsÚloggingÚ	getLoggerr€   Ú	fixer_logÚwroter   ÚDriverr	   r   Ú
get_fixersÚ	pre_orderÚ
post_orderÚfilesÚbmÚBottomMatcherÚBMÚbmi_pre_orderÚbmi_post_orderr   ÚBM_compatibleÚ	add_fixerr   rJ   Úbmi_pre_order_headsÚbmi_post_order_heads)ÚselfÚfixer_namesr…   r‚   rG   s        r   Ú__init__zRefactoringTool.__init__¤   sÛ  € ð "ˆŒØ š BˆŒØ×,Ñ,×1Ñ1Ó3ˆŒØÐØ�L‰L×Ñ Ô(Ü×,Ñ,×1Ñ1Ó3ˆŒà�<‰<Ð(Ò)Ø—‘×%Ñ% gÑ.Ø�\‰\˜/Ò*Ø—‘×%Ñ% fÐ-ð
 &*§\¡\×%5Ñ%5Ð6MÓ%NˆÔ"ØˆŒÜ×'Ñ'Ð(9Ó:ˆŒØˆŒØˆŒ
Ü—m‘m D§L¡LÜ,2¯N©NØ+/¯;©;ô8ˆŒð +/¯/©/Ó*;Ñ'ˆŒ˜œð ˆŒ
ä×"Ñ"Ó$ˆŒØˆÔØ ˆÔä˜4Ÿ?™?¨D¯N©NÖ;ˆEØ×"Ò"Ø—‘×!Ñ! %Õ(ð ˜$Ÿ.™.Ñ(Ø×"Ñ"×)Ñ)¨%Õ0Ø˜$Ÿ/™/Ò)Ø×#Ñ#×*Ñ*¨5Õ1ð <ô $6°d×6HÑ6HÓ#IˆÔ Ü$6°t×7JÑ7JÓ$KˆÕ!r   c           	      óÚ  — g }g }| j                   D �]w  }t        |i i dg«      }|j                  dd«      d   }|j                  | j                  «      r|t        | j                  «      d }|j                  d«      }| j                  dj                  |D �cg c]  }|j                  «       ‘Œ c}«      z   }	 t        ||«      }	 |	| j                  | j                  «      }
|
j                  r0| j                  d	ur"|| j                  vr| j!                  d
|«       �Œ| j#                  d|«       |
j$                  dk(  r|j'                  |
«       �Œ@|
j$                  dk(  r|j'                  |
«       �Œbt        d|
j$                  z  «      ‚ t)        j*                  d«      }|j-                  |¬«       |j-                  |¬«       ||fS c c}w # t        $ r t        d|›d|›�«      d‚w xY w)a  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   rL   r   éÿÿÿÿNÚ_Ú zCan't find TzSkipping optional fixer: %szAdding transformation: %sÚpreÚpostzIllegal fixer order: %rÚ	run_order©Úkey)r�   r   Úrsplitr   ÚFILE_PREFIXÚlenÚsplitÚCLASS_PREFIXÚjoinÚtitleÚgetattrÚAttributeErrorrt   r…   rŒ   r‚   Úlog_messageÚ	log_debugÚorderr   ÚoperatorÚ
attrgetterÚsort)rœ   Úpre_order_fixersÚpost_order_fixersÚfix_mod_pathÚmodrN   Úpartsr6   Ú
class_nameÚ	fix_classrG   Úkey_funcs               r   r�   zRefactoringTool.get_fixersÛ   sÍ  € ð ÐØÐØ ŸK�KˆLÜ˜\¨2¨r°C°5Ó9ˆCØ#×*Ñ*¨3°Ó2°2Ñ6ˆHØ×"Ñ" 4×#3Ñ#3Ô4Ø#¤C¨×(8Ñ(8Ó$9Ð$:Ð;�Ø—N‘N 3Ó'ˆEØ×*Ñ*¨R¯W©WÉÓ5OÉÀA°a·g±gµiÈÑ5OÓ-PÑPˆJðXÜ# C¨Ó4�	ñ ˜dŸl™l¨D¯N©NÓ;ˆEØ�~Š~ $§-¡-°tÑ";Ø ¨¯©Ñ5Ø× Ñ Ð!>ÀÔIÙà�N‰NÐ6¸ÔAØ�{‰{˜eÒ#Ø ×'Ñ'¨Ö.Ø—‘ Ò&Ø!×(Ñ(¨Ö/ä Ð!:¸U¿[¹[Ñ!HÓIÐIð/ (ô2 ×&Ñ& {Ó3ˆØ×Ñ (ÐÔ+Ø×Ñ 8ÐÔ,Ø Ð"3Ð4Ð4ùò- 6Pøô "ò XÝ ²xÁÐ!LÓMÐSWÐWðXús   ÂG	Â8GÇG*c                  ó   — ‚ )zCalled when an error occurs.r&   )rœ   ÚmsgÚargsÚkwdss       r   Ú	log_errorzRefactoringTool.log_error  s   € àr   c                 óH   — |r||z  }| j                   j                  |«       y)zHook to log a message.N)r€   Úinfo©rœ   rÀ   rÁ   s      r   r±   zRefactoringTool.log_message  s    € áØ˜‘*ˆCØ�‰×Ñ˜Õr   c                 óH   — |r||z  }| j                   j                  |«       y rQ   )r€   ÚdebugrÆ   s      r   r²   zRefactoringTool.log_debug  s    € ÙØ˜‘*ˆCØ�‰×Ñ˜#Õr   c                  ó   — y)zTCalled with the old version, new version, and filename of a
        refactored file.Nr&   )rœ   Úold_textÚnew_textÚfilenameÚequals        r   Úprint_outputzRefactoringTool.print_output  s   € ð 	r   c                 óž   — |D ]H  }t         j                  j                  |«      r| j                  |||«       Œ6| j	                  |||«       ŒJ y)z)Refactor a list of files and directories.N)ÚosÚpathÚisdirÚrefactor_dirÚrefactor_file)rœ   ÚitemsÚwriteÚdoctests_onlyÚdir_or_files        r   ÚrefactorzRefactoringTool.refactor  sB   € ó !ˆKÜ�w‰w�}‰}˜[Ô)Ø×!Ñ! +¨u°mÕDà×"Ñ" ;°°}ÕEñ	 !r   c                 ó  — t         j                  dz   }t        j                  |«      D ]Ï  \  }}}| j                  d|«       |j	                  «        |j	                  «        |D ]m  }|j                  d«      rŒt         j                  j                  |«      d   |k(  sŒ;t         j                  j                  ||«      }	| j                  |	||«       Œo |D �
cg c]  }
|
j                  d«      rŒ|
‘Œ c}
|dd ŒÑ yc c}
w )zÄ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.
        ÚpyzDescending into %srL   r   N)
rÐ   ÚextsepÚwalkr²   r¶   r   rÑ   Úsplitextr­   rÔ   )rœ   Údir_namerÖ   r×   Úpy_extÚdirpathÚdirnamesÚ	filenamesr   ÚfullnameÚdns              r   rÓ   zRefactoringTool.refactor_dir   sÑ   € ô —‘˜TÑ!ˆÜ,.¯G©G°HÖ,=Ñ(ˆG�X˜yØ�N‰NÐ/°Ô9Ø�M‰MŒOØ�N‰NÔÛ!�ØŸ™¨Õ,Ü—G‘G×$Ñ$ TÓ*¨1Ñ-°Ó7Ü!Ÿw™wŸ|™|¨G°TÓ:�HØ×&Ñ& x°¸ÕFð	 "ñ )1ÓK© "¸¿¹ÀcÕ8Jš2¨ÑKˆH‘Q‰Kñ ->ùò Ls   ÃC<Ã/C<c                 ó€  — 	 t        |d«      }	 t        j                  |j
                  «      d   }|j                  «        t        j                   |d|d¬«      5 }|j                  «       |fcddd«       S # t        $ r}| j                  d||«       Y d}~yd}~ww xY w# |j                  «        w xY w# 1 sw Y   yxY w)	zG
        Do our best to decode a Python source file correctly.
        ÚrbzCan't open %s: %sN©NNr   r5   r¢   ©ÚencodingÚnewline)	ÚopenÚOSErrorrÃ   r   Údetect_encodingrb   Úcloser`   Úread)rœ   rÌ   ÚfÚerrrê   s        r   Ú_read_python_sourcez#RefactoringTool._read_python_source4  sž   € ð	Ü�X˜tÓ$ˆAð	Ü×/Ñ/°·
±
Ó;¸AÑ>ˆHà�G‰GŒIÜ�W‰W�X˜s¨X¸rÕBÀaØ—6‘6“8˜XÐ%÷ CÑBøô ò 	Ø�N‰NÐ.°¸#Ô>Üûð	ûð �G‰G�IúßBÐBús.   ‚A6 �"B ÁB4Á6	BÁ?BÂBÂB1Â4B=c                 ó¼  — | j                  |«      \  }}|€y|dz  }|r^| j                  d|«       | j                  ||«      }| j                  s||k7  r| j	                  |||||«       y| j                  d|«       y| j                  ||«      }| j                  s|r.|j                  r"| j	                  t        |«      dd |||¬«       y| j                  d|«       y)zRefactors a file.NÚ
zRefactoring doctests in %szNo doctest changes in %sr    )rÖ   rê   zNo changes in %s)ró   r²   Úrefactor_docstringrz   Úprocessed_fileÚrefactor_stringÚwas_changedÚstr)rœ   rÌ   rÖ   r×   Úinputrê   ÚoutputÚtrees           r   rÔ   zRefactoringTool.refactor_fileD  sÜ   € à×2Ñ2°8Ó<‰ˆˆxØˆ=àØ�‰ˆÙØ�N‰NÐ7¸ÔBØ×,Ñ,¨U°HÓ=ˆFØ×)Ò)¨V°uª_Ø×#Ñ# F¨H°e¸UÀHÕMà—‘Ð9¸8ÕDà×'Ñ'¨¨xÓ8ˆDØ×)Ò)©d°t×7GÒ7Gà×#Ñ#¤C¨£I¨c¨r N°HØ*/¸(ð $õ Dð —‘Ð1°8Õ<r   c                 ó  — t        |«      }d|v rt        j                  | j                  _        	 | j                  j                  |«      }	 | j                  | j                  _        ||_
        | j                  d|«       | j                  ||«       |S # t        $ rM}| j                  d||j                  j                  |«       Y d}~| j                  | j                  _        yd}~ww xY w# | j                  | j                  _        w xY w)aF  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.
        rx   zCan't parse %s: %s: %sNzRefactoring %s)rr   r
   Ú!python_grammar_no_print_statementr   r†   Úparse_stringr3   rÃ   Ú	__class__r#   Úfuture_featuresr²   Úrefactor_tree)rœ   Údatar   ro   rý   rò   s         r   rø   zRefactoringTool.refactor_string[  s×   € ô +¨4Ó0ˆØ˜xÑ'Ü"(×"JÑ"JˆD�K‰KÔð	/Ø—;‘;×+Ñ+¨DÓ1‰Dð #'§,¡,ˆD�K‰KÔØ'ˆÔØ�‰Ð'¨Ô.Ø×Ñ˜4 Ô&Øˆøô ò 	Ø�N‰NÐ3Ø §¡×!7Ñ!7¸ô>ãà"&§,¡,ˆD�K‰KÕûð	ûð
 #'§,¡,ˆD�K‰KÕús)   °B Â	C*Â(C%ÃC- Ã%C*Ã*C- Ã-D
c                 ó¬  — t         j                  j                  «       }|rZ| j                  d«       | j	                  |d«      }| j
                  s||k7  r| j                  |d|«       y | j                  d«       y | j                  |d«      }| j
                  s|r)|j                  r| j                  t        |«      d|«       y | j                  d«       y )NzRefactoring doctests in stdinz<stdin>zNo doctest changes in stdinzNo changes in stdin)
ÚsysÚstdinrð   r²   rö   rz   r÷   rø   rù   rú   )rœ   r×   rû   rü   rý   s        r   Úrefactor_stdinzRefactoringTool.refactor_stdinv  sª   € Ü—	‘	—‘Ó ˆÙØ�N‰NÐ:Ô;Ø×,Ñ,¨U°IÓ>ˆFØ×)Ò)¨V°uª_Ø×#Ñ# F¨I°uÕ=à—‘Ð<Õ=à×'Ñ'¨¨yÓ9ˆDØ×)Ò)©d°t×7GÒ7GØ×#Ñ#¤C¨£I¨y¸%Õ@à—‘Ð4Õ5r   c                 óà  — t        | j                  | j                  «      D ]  }|j                  ||«       Œ | j	                  | j
                  |j                  «       «       | j	                  | j                  |j                  «       «       | j                  j                  |j                  «       «      }t        |j                  «       «      �rÎ| j                  j                  D �]™  }||v sŒ	||   sŒ||   j                  t        j                  j                   d¬«       |j"                  r-||   j                  t        j                  j$                  ¬«       t'        ||   «      D �]  }|||   v r||   j)                  |«       	 t+        |«       |j.                  r||j.                  v rŒF|j1                  |«      }|sŒZ|j3                  ||«      }|€Œo|j5                  |«       |j                  «       D ]0  }|j.                  sg |_        |j.                  j7                  |«       Œ2 | j                  j                  |j                  «       «      }|D ]"  }	|	|vrg ||	<   ||	   j9                  ||	   «       Œ$ �Œ �Œœ t        |j                  «       «      r�ŒÎt        | j                  | j                  «      D ]  }|j;                  ||«       Œ |j<                  S # t,        $ r Y �Œƒw xY w)aÏ  Refactors a parse tree (modifying the tree in place).

        For compatible patterns the bottom matcher module is
        used. Otherwise the tree is traversed node-to-node for
        matches.

        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.
        T)r§   Úreverser¦   )r   r�   r‘   Ú
start_treeÚtraverse_byrš   r›   r•   ÚrunÚleavesÚanyr@   r�   r¶   r	   ÚBaseÚdepthÚkeep_line_orderÚ
get_linenor;   Úremover   Ú
ValueErrorÚfixers_appliedÚmatchÚ	transformÚreplacer   rB   Úfinish_treerù   )
rœ   rý   r   rG   Ú	match_setÚnodeÚresultsÚnewÚnew_matchesÚfxrs
             r   r  zRefactoringTool.refactor_tree†  sv  € ô  ˜4Ÿ>™>¨4¯?©?Ö;ˆEØ×Ñ˜T 4Õ(ð <ð 	×Ñ˜×1Ñ1°4·>±>Ó3CÔDØ×Ñ˜×2Ñ2°D·O±OÓ4EÔFð —G‘G—K‘K §¡£Ó.ˆ	ä�)×"Ñ"Ó$Õ%ØŸ™Ÿ��Ø˜IÒ%¨)°EÓ*:à˜eÑ$×)Ñ)¬f¯k©k×.?Ñ.?ÈÐ)ÔNà×,Ò,ð " %Ñ(×-Ñ-´&·+±+×2HÑ2HÐ-ÔIä $ Y¨uÑ%5× 6˜Ø 9¨UÑ#3Ñ3Ø% eÑ,×3Ñ3°DÔ9ð%Ü% dœOð  ×.Ò.°5¸D×<OÑ<OÑ3Oà$à"'§+¡+¨dÓ"3˜â"Ø"'§/¡/°$¸Ó"@˜CØ"™Ø $§¡¨SÔ 1à,/¯N©NÖ,< Dð ,0×+>Ò+>Ø>@¨Ô(;Ø$(×$7Ñ$7×$>Ñ$>¸uÕ$Eð -=ð /3¯g©g¯k©k¸#¿*¹*»,Ó.G Û+6 CØ+.°)Ñ+;Ø79¨	°#©à$-¨c¡N×$9Ñ$9¸+ÀcÑ:JÕ$Kò	 ,7òA !7ð (ô �)×"Ñ"Ó$Ö%ôb ˜4Ÿ>™>¨4¯?©?Ö;ˆEØ×Ñ˜d DÕ)ð <à×ÑÐøôE  *ò %ò %ð%ús   Æ	K Ë 	K-Ë,K-c                 ó¸   — |sy|D ]R  }||j                      D ]>  }|j                  |«      }|sŒ|j                  ||«      }|€Œ,|j                  |«       |}Œ@ ŒT y)a  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  r  r  )rœ   r�   Ú	traversalr  rG   r  r  s          r   r  zRefactoringTool.traverse_byÕ  s^   € ñ ØÛˆDØ §	¡	Ô*�ØŸ+™+ dÓ+�ÚØŸ/™/¨$°Ó8�CØ‘ØŸ™ SÔ)Ø"™ñ +ñ r   c                 ó2  — | j                   j                  |«       |€| j                  |«      d   }|€y||k(  }| j                  ||||«       |r| j	                  d|«       | j
                  sy|r| j                  ||||«       y| j	                  d|«       y)zR
        Called when a file has been refactored and there may be changes.
        Nr   zNo changes to %szNot writing changes to %s)r’   r   ró   rÎ   r²   rz   Ú
write_file)rœ   rË   rÌ   rÊ   rÖ   rê   rÍ   s          r   r÷   zRefactoringTool.processed_fileì  sš   € ð
 	�
‰
×Ñ˜(Ô#ØÐØ×/Ñ/°Ó9¸!Ñ<ˆHØÐØØ˜HÑ$ˆØ×Ñ˜( H¨h¸Ô>ÙØ�N‰NÐ-¨xÔ8Ø×-Ò-ØÙØ�O‰O˜H h°¸(ÕCà�N‰NÐ6¸ÕAr   c                 ó`  — 	 t        j                  |d|d¬«      }|5  	 |j	                  |«       ddd«       | j                  d|«       d| _        y# t        $ r}| j                  d||«       Y d}~yd}~ww xY w# t        $ r}| j                  d||«       Y d}~Œld}~ww xY w# 1 sw Y   ŒuxY w)	zÑ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.
        Úwr¢   ré   zCan't create %s: %sNzCan't write %s: %szWrote changes to %sT)r`   rì   rí   rÃ   rÖ   r²   r�   )rœ   rË   rÌ   rÊ   rê   Úfprò   s          r   r$  zRefactoringTool.write_file  s¤   € ð	Ü—‘˜ 3°À2ÔFˆBò
 ðDØ—‘˜Ô"÷ ð
 	�‰Ð,¨hÔ7Øˆ�
øô ò 	Ø�N‰NÐ0°(¸CÔ@Üûð	ûô ò DØ—‘Ð3°X¸s×CÑCûðDú÷ ˆRúsE   ‚A �B$ŸA;Á	A8ÁA3Á3A8Á;	B!ÂBÂB$ÂB!Â!B$Â$B-z>>> z... c           	      óÄ  — g }d}d}d}d}|j                  d¬«      D �]  }|dz  }|j                  «       j                  | j                  «      rK|�#|j	                  | j                  ||||«      «       |}|g}|j                  | j                  «      }	|d|	 }Œ}|�S|j                  || j                  z   «      s#||| j                  j                  «       z   dz   k(  r|j                  |«       ŒÒ|�#|j	                  | j                  ||||«      «       d}d}|j                  |«       �Œ |�#|j	                  | j                  ||||«      «       dj                  |«      S )aË  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.)
        Nr   T©Úkeependsr   rõ   r¢   )Ú
splitlinesÚlstripr   ÚPS1rB   Úrefactor_doctestÚfindÚPS2Úrstripr   r­   )
rœ   rû   rÌ   ÚresultÚblockÚblock_linenoÚindentÚlinenoÚlineÚis
             r   rö   z"RefactoringTool.refactor_docstring  sg  € ð ˆØˆØˆØˆØˆØ×$Ñ$¨dÐ$×3ˆDØ�a‰KˆFØ�{‰{‹}×'Ñ'¨¯©Ô1ØÐ$Ø—M‘M $×"7Ñ"7¸¸|Ø8>Àó#Jô Kà%�Ø˜�Ø—I‘I˜dŸh™hÓ'�Ø˜b˜q˜‘ØÐ$Ø—?‘? 6¨D¯H©HÑ#4Ô5Ø˜6 D§H¡H§O¡OÓ$5Ñ5¸Ñ<Ò<Ø—‘˜TÕ"àÐ$Ø—M‘M $×"7Ñ"7¸¸|Ø8>Àó#Jô Kà�Ø�Ø—‘˜dÖ#ð) 4ð* ÐØ�M‰M˜$×/Ñ/°°|Ø06¸óBô Cà�w‰w�v‹Ðr   c                 óÌ  — 	 | j                  |||«      }| j                  ||«      r¦t        |«      j                  d¬«      }|d|dz
   ||dz
  d }}	|	dg|dz
  z  k(  sJ |	«       ‚|d   j                  d«      s|dxx   dz  cc<   || j                  z   |j!                  d	«      z   g}|r#||D �cg c]  }|| j"                  z   |z   ‘Œ c}z  }|S # t        $ r†}| j                  j                  t        j
                  «      r(|D ]#  }| j                  d|j                  d«      «       Œ% | j                  d|||j                  j                  |«       |cY d}~S d}~ww xY wc c}w )
zÞ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).

        z
Source: %srõ   z+Can't parse docstring in %s line %s: %s: %sNTr)  r   r    r   )Úparse_blockr3   r€   ÚisEnabledForrŠ   ÚDEBUGr²   r1  rÃ   r  r#   r  rú   r+  Úendswithr-  Úpopr0  )
rœ   r3  r6  r5  rÌ   rý   rò   r7  r  Úclippeds
             r   r.  z RefactoringTool.refactor_doctestD  sa  € ð	Ø×#Ñ# E¨6°6Ó:ˆDð ×Ñ˜d HÔ-Ü�d“)×&Ñ&°Ð&Ó5ˆCà˜y  q¡˜>¨3¨v°a©x¨y¨>�SˆGØ˜t˜f¨¨q©Ñ1Ò1Ð:°7Ó:Ð1Ø�r‘7×#Ñ# DÔ)Ø�B“˜4‘“Ø˜dŸh™hÑ&¨¯©°«Ñ3Ð4ˆEÙØ¹sÓC¹s°t˜& 4§8¡8Ñ+¨dÓ2¸sÑCÑC�Øˆøô# ò 	Ø�{‰{×'Ñ'¬¯©Ô6Û!�DØ—N‘N <°·±¸TÓ1BÕCð "à�N‰NÐHØ# V¨S¯]©]×-CÑ-CÀSôJà�Lûð	üò  Ds$   ‚C Â/E!Ã	EÃA;EÅEÅEc                 óX  — | j                   rd}nd}| j                  s| j                  d|«       n4| j                  d|«       | j                  D ]  }| j                  |«       Œ | j                  r3| j                  d«       | j                  D ]  }| j                  |«       Œ | j                  r{t        | j                  «      dk(  r| j                  d«       n%| j                  dt        | j                  «      «       | j                  D ]  \  }}} | j                  |g|¢­i |¤Ž Œ y y )	NÚwerez
need to bezNo files %s modified.zFiles that %s modified:z$Warnings/messages while refactoring:r   zThere was 1 error:zThere were %d errors:)r�   r’   r±   rŒ   r‰   rª   )rœ   rA  ÚfileÚmessagerÀ   rÁ   rÂ   s          r   Ú	summarizezRefactoringTool.summarizea  sþ   € Ø�:Š:Ø‰DàˆDØ�zŠzØ×ÑÐ4°dÕ;à×ÑÐ6¸Ô=ØŸ
œ
�Ø× Ñ  Õ&ð #à�>Š>Ø×ÑÐCÔDØŸ>œ>�Ø× Ñ  Õ)ð *à�;Š;Ü�4—;‘;Ó 1Ò$Ø× Ñ Ð!5Õ6à× Ñ Ð!8¼#¸d¿k¹kÓ:JÔKØ#'§;¤;‘��T˜4Ø �× Ñ  Ð4 tÒ4¨tÓ4ñ $/ð r   c                 ó|   — | j                   j                  | j                  |||«      «      }t        «       |_        |S )z³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   Úparse_tokensÚ	wrap_toksrc   r  )rœ   r3  r6  r5  rý   s        r   r:  zRefactoringTool.parse_blockx  s4   € ð �{‰{×'Ñ'¨¯©°u¸fÀfÓ(MÓNˆÜ(›{ˆÔØˆr   c              #   óÊ   K  — t        j                  | j                  ||«      j                  «      }|D ]+  \  }}\  }}\  }	}
}||dz
  z  }|	|dz
  z  }	||||f|	|
f|f–— Œ- y­w)z;Wraps a tokenize stream to systematically modify start/end.r   N)r   r_   Ú	gen_linesÚ__next__)rœ   r3  r6  r5  rA   r,   rq   Úline0Úcol0Úline1Úcol1Ú	line_texts               r   rG  zRefactoringTool.wrap_toks‚  s}   è ø€ ä×)Ñ)¨$¯.©.¸ÀÓ*G×*PÑ*PÓQˆÛDJÑ@ˆD�%™˜% ©¨°°yØ�V˜a‘ZÑˆEØ�V˜a‘ZÑˆEð ˜  t˜}¨u°d¨m¸YÐFÓFñ EKùs   ‚A!A#c              #   ó  K  — || j                   z   }|| j                  z   }|}|D ]R  }|j                  |«      r|t        |«      d –— n,||j	                  «       dz   k(  rd–— nt        d|›d|›�«      ‚|}ŒT 	 d–— Œ­w)z–Generates lines as expected by tokenize from a list of lines.

        This strips the first len(indent + self.PS1) characters off each line.
        Nrõ   zline=z	, prefix=r¢   )r-  r0  r   rª   r1  ÚAssertionError)rœ   r3  r5  Úprefix1Úprefix2Úprefixr7  s          r   rI  zRefactoringTool.gen_lines�  sŒ   è ø€ ð
 ˜4Ÿ8™8Ñ#ˆØ˜4Ÿ8™8Ñ#ˆØˆÛˆDØ�‰˜vÔ&Øœ3˜v›;˜<Ð(Ó(Ø˜Ÿ™›¨4Ñ/Ò/Ø“
å$ºTÁ6Ð%JÓKÐKØ‰Fð ð ØŠHð ùs   ‚A>B rè   )FF)F)NFNrQ   )r#   r$   r%   rƒ   r¬   r©   rž   r�   rÃ   r±   r²   rÎ   rÙ   rÓ   ró   rÔ   rø   r  r  r  r÷   r$  r-  r0  rö   r.  rD  r:  rG  rI  r&   r   r   rw   rw   ›   s­   „ à+0Ø).Ø27ñ9Ðð €LØ€Kó3Lòn&5òPòòò
ó
FóLò(&ó =ò.ó66ò M ò^#ð. GLØ $óBó*ð* €CØ
€Cò)òVò:5ò.òGór   rw   c                   ó   — e Zd Zy)ÚMultiprocessingUnsupportedNr"   r&   r   r   rV  rV  ¤  r'   r   rV  c                   óB   ‡ — e Zd Zˆ fd„Z	 	 dˆ fd„	Zˆ fd„Zˆ fd„Zˆ xZS )ÚMultiprocessRefactoringToolc                 óH   •— t        t        | �
  |i |¤Ž d | _        d | _        y rQ   )ÚsuperrX  rž   ÚqueueÚoutput_lock©rœ   rÁ   Úkwargsr  s      €r   rž   z$MultiprocessRefactoringTool.__init__ª  s'   ø€ ÜÔ)¨4Ñ9¸4ÐJÀ6ÒJØˆŒ
ØˆÕr   c                 óŽ  •— |dk(  rt         t        | �  |||«      S 	 dd l}| j                  �t        d«      ‚|j                  «       | _        |j                  «       | _
        t        |«      D �cg c]  }|j                  | j                  ¬«      ‘Œ  }}	 |D ]  }|j                  «        Œ t         t        | �  |||«       | j                  j                  «        t        |«      D ]  }| j                  j!                  d «       Œ |D ]#  }|j#                  «       sŒ|j                  «        Œ% d | _        y # t        $ r t
        ‚w xY wc c}w # | j                  j                  «        t        |«      D ]  }| j                  j!                  d «       Œ |D ]#  }|j#                  «       sŒ|j                  «        Œ% d | _        w xY w)Nr   r   z already doing multiple processes)Útarget)rZ  rX  rÙ   ÚmultiprocessingÚImportErrorrV  r[  ÚRuntimeErrorÚJoinableQueueÚLockr\  ÚrangeÚProcessÚ_childÚstartr­   ÚputÚis_alive)
rœ   rÕ   rÖ   r×   Únum_processesra  r8  Ú	processesr6   r  s
            €r   rÙ   z$MultiprocessRefactoringTool.refactor¯  s”  ø€ à˜AÒÜÔ4°dÑDØ�u˜mó-ð -ð	-Û"ð �:‰:Ð!ÜÐAÓBÐBØ$×2Ñ2Ó4ˆŒ
Ø*×/Ñ/Ó1ˆÔä# MÔ2ó4Ù2˜ð %×,Ñ,°D·K±KÐ,Õ@Ø2ð 	ð 4ð	Û�Ø—‘•	ð äÔ-¨tÑ=¸eÀUØ>KôMð �J‰J�O‰OÔÜ˜=Ö)�Ø—
‘
—‘˜tÕ$ð *ã�Ø—:‘:•<Ø—F‘F•Hð ð ˆD�Jøô) ò 	-Ü,Ð,ð	-üò4øð �J‰J�O‰OÔÜ˜=Ö)�Ø—
‘
—‘˜tÕ$ð *ã�Ø—:‘:•<Ø—F‘F•Hð ð ˆD�Jús$   �D6 Á/#E	Â,E Ä6EÅAGÆ*Gc                 ó  •— | j                   j                  «       }|�Q|\  }}	 t        t        | �  |i |¤Ž | j                   j                  «        | j                   j                  «       }|�ŒPy y # | j                   j                  «        w xY wrQ   )r[  rˆ   rZ  rX  rÔ   Ú	task_done)rœ   ÚtaskrÁ   r^  r  s       €r   rh  z"MultiprocessRefactoringTool._childÌ  s€   ø€ Ø�z‰z�~‰~ÓˆØÐØ‰LˆD�&ð'ÜÔ1°4ÑFØð%Ø#ò%ð —
‘
×$Ñ$Ô&Ø—:‘:—>‘>Ó#ˆDð Óøð —
‘
×$Ñ$Õ&ús   ¤A0 Á0Bc                 ó~   •— | j                   �| j                   j                  ||f«       y t        t        | �  |i |¤ŽS rQ   )r[  rj  rZ  rX  rÔ   r]  s      €r   rÔ   z)MultiprocessRefactoringTool.refactor_file×  sA   ø€ Ø�:‰:Ð!Ø�J‰J�N‰N˜D &˜>Õ*äÔ4°dÑIØð!Øñ!ð !r   )FFr   )r#   r$   r%   rž   rÙ   rh  rÔ   Ú__classcell__)r  s   @r   rX  rX  ¨  s$   ø„ ô ð
 :?Ø õô:	$÷!ð !r   rX  )T)#ru   Ú
__author__r`   rÐ   r   r  rŠ   r´   r9   Ú	itertoolsr   Úpgen2r   r   r   Ú
fixer_utilr   r¢   r	   r
   r   r“   r   r3   r!   r/   rJ   rO   rS   rr   rt   Úobjectrw   rV  rX  r&   r   r   Ú<module>rx     sœ   ðñð 3€
ó 
Û 	Û Û 
Û Û Û Ý ÷ +Ñ *Ý !ß Ý ó	ô	�ô 	òCò8ò2@òò%ôP'�ô 'ôF�fô FôR	 ô 	ô4! /õ 4!r   