B ÍAÒ[VDã@s\dZddlmZmZmZmZmZmZddlm Z m Z ddl m Z mZddl mZddlm Z mZmZm Z mZmZddlZdd „Zd4d d „Zd5d d „Zd6dd„Zdd„Zdd„Zdd„Zdd„Zd7dd„Ze je je je j e j!fZ"e j#e j$fZ%dd„Z&d8dd„Z'dd„Z(d d!„Z)d"d#„Z*d$d%„Z+d&d'„Z,d(d)„Z-d*d+„Z.d,Z/d-Z0d.d/„Z1d0d1„Z2d9d2d3„Z3dS):zå Utility functions from 2to3, 3to2 and python-modernize (and some home-grown ones). Licences: 2to3: PSF License v2 3to2: Apache Software License (from 3to2/setup.py) python-modernize licence: BSD (from python-modernize/LICENSE) é)Ú FromImportÚNewlineÚ is_importÚ find_rootÚdoes_tree_importÚComma)ÚLeafÚNode)Úpython_symbolsÚpython_grammar)Útoken)r ÚCallÚNameÚsymsrÚNumberNcs~dˆkr ˆSˆ d¡r"ˆdd…‰‡fdd„|Dƒ}t|ƒdkr^tdd  d d „|Dƒ¡ƒ‚nt|ƒd krrtd ƒ‚|d SdS)al Examples: >>> canonical_fix_name('fix_wrap_text_literals') 'libfuturize.fixes.fix_wrap_text_literals' >>> canonical_fix_name('wrap_text_literals') 'libfuturize.fixes.fix_wrap_text_literals' >>> canonical_fix_name('wrap_te') ValueError("unknown fixer name") >>> canonical_fix_name('wrap') ValueError("ambiguous fixer name") z.fix_Zfix_éNcs g|]}| d ˆ¡¡r|‘qS)zfix_{0})ÚendswithÚformat)Ú.0Úf)Úfix©úG/opt/alt/python37/lib/python3.7/site-packages/libfuturize/fixer_util.pyú (sz&canonical_fix_name..ézOAmbiguous fixer name. Choose a fully qualified module name instead from these: Ú css|]}d|VqdS)z Nr)rZmyfrrrú -sz%canonical_fix_name..rz1Unknown fixer. Use --list-fixes or -l for a list.)Ú startswithÚlenÚ ValueErrorÚjoin)rZ avail_fixesÚfoundr)rrÚcanonical_fix_names     r"cCsttjd|d�S)NÚ*)Úprefix)rr ÚSTAR)r$rrrÚStar6sr&cCsttjd|d�S)Nz**)r$)rr Ú DOUBLESTAR)r$rrrÚ DoubleStar9sr(cCsttjd|d�S)Nú-)r$)rr ÚMINUS)r$rrrÚMinus<sr+cCs2g}x"|D]}| |¡| tƒ¡q W|d=|S)z{ Accepts/turns: (Name, Name, ..., Name, Name) Returns/into: (Name, Comma, Name, Comma, ..., Name, Comma, Name) éÿÿÿÿ)Úappendr)ZleafsZ new_leafsZleafrrrÚ commatize?s   r.cCs|x"|jdk r"|jjtjkr"|j}qW|jdkr2dS|jtjkrD|jS|jdk rd|jjtjkrd|jjS|jdkrrdS|jSdS)zf Returns the indentation for this node Iff a node is in a suite, then it has indentation. NÚ) ÚparentÚtyperÚsuiter ÚINDENTÚvalueZ prev_siblingr$)ÚnoderrrÚ indentationKs    r6cCs2t|ƒ}tdd„| ¡Dƒƒ}|s&dSt|ƒSdS)a Dirty little trick to get the difference between each indentation level Implemented by finding the shortest indentation string (technically, the "least" of all of the indentation strings, but tabs and spaces mixed won't get this far, so those are synonymous.) css |]}|jtjkr|jVqdS)N)r1r r3r4)rÚirrrrisz#indentation_step..z N)rÚsetZ pre_orderÚmin)r5ÚrZ all_indentsrrrÚindentation_step`s r;cCs¨x|jD]}|jtjkrdSqWx,t|jƒD]\}}|jtjkr,Pq,Wtdƒ‚ttjt ƒt tj t |ƒt |ƒƒgƒ}|j|d}| ¡d|_| |¡| |¡dS)zj Turn the stuff after the first colon in parent's children into a suite, if it wasn't already NzNo class suite and no ':'!rr/)Úchildrenr1rr2Ú enumerater ÚCOLONrr rrr3r6r;Úremover$Z append_child)r0r5r7r2Zone_noderrrÚsuitifyps   & r@cCsN|dkr d}td|d�|g}|dk rB| tddd�t|dd�g¡ttj|ƒS)z— Accepts a package (Name node), name to import it as (string), and optional prefix and returns a node: import [as ] Nr/Úimport)r$Úasú )rÚextendr rÚ import_name)ÚpackageÚas_namer$r<rrrÚ NameImportˆsrHccs|jtkst‚|j}x2|jtjkrF|j}|jtjkr8Pn|V|j}qW|j}|jtj ks^t‚|j}x|dk r||V|j}qfW|j}|jt kr¶|}x|jdk r®|jV|j}q”W|j}|j}|dkrÈdSxF|jt k�r|jtj krè|V|j}|dkrÊ|j}|j}|dkrÊPqÊWdS)z‘ Generator yields all nodes for which a node (an import_stmt) has scope The purpose of this is for a call to _find() on each of them N) r1Ú _import_stmtsÚAssertionErrorÚ next_siblingr ÚSEMIÚNEWLINEr0rÚ simple_stmtÚ_compound_stmtsr2)r5ÚtestZnxtr0ÚcontextÚcÚprrrÚimport_binding_scope™sB        rTcCsDt|ƒ}tddd�}t|dd�}ttj|||gƒ}|dk r@||_|S)NrBrC)r$)rr rÚimport_as_namer$)ÚnamerGr$Únew_nameZnew_asZ new_as_nameÚnew_noderrrÚ ImportAsNameÔs  rYcCs,|jtjko*t|jƒdko*|jdjtjkS)z< Returns True if the node appears to be a docstring r)r1rrNrr<r ÚSTRING)r5rrrÚ is_docstringÞs r[cCsÐt|ƒ}td||ƒrdSd}xNt|jƒD]@\}}t|ƒs@t|ƒrD|}t|ƒrNq(t|ƒ}|s\P||kr(dSq(Wtdt t j |dd�gƒ}|dkr®|dkr®|jdj |_ d|jd_ |t ƒg}| |ttj|ƒ¡dS)z This seems to work Ú __future__NrC)r$rr/)rrr=r<Úis_shebang_commentÚis_encoding_commentr[Úcheck_future_importrrr ÚNAMEr$rÚ insert_childr rrN)Úfeaturer5ÚrootZshebang_encoding_idxÚidxÚnamesÚimport_r<rrrÚ future_importæs(   rgc Csàt|ƒ}td||ƒrdSd}xDt|jƒD]6\}}|jtjkr(|jr(|jdjtjkr(|d}Pq(Wx>|j|d…D](}|jtj krŒ|d7}qr|j }d|_ PqrWd}t dt tj |dd�gƒ}|tƒg}| |ttj||d�¡dS)zD An alternative to future_import() which might not work ... r\Nrrr/rC)r$)rrr=r<r1rrNr rZrMr$rrr`rrar ) rbr5rcÚ insert_posrdZ thing_afterr$rfr<rrrÚfuture_import2s(   ricCs„dd„|Dƒ}tdd„|Dƒƒ}x^t|ƒD]R\}}|jtjkrl|jdjtjkrl|jdj}|jd||<q*||}|||<q*W|S)z/ Parse a list of arguments into a dict cSsg|]}|jtjkr|‘qSr)r1r ÚCOMMA)rr7rrrr2szparse_args..cSsg|] }|df‘qS)Nr)rÚkrrrr4srré) Údictr=r1rZargumentr<r ÚEQUALr4)ZarglistÚschemeZ ret_mappingr7ÚargZslotrrrÚ parse_args.s  rqcCs |jtjko|jot|jdƒS)Nr)r1rrNr<r)r5rrrÚis_import_stmtHsrrc Cs t|ƒ}t|||ƒrdSd}xdD]}td||ƒr"d}Pq"W|r¶d\}}xNt|jƒD]@\}}t|ƒrT|}|} x$|r�|j}| d7} t|ƒsn| }PqnWPqTW|dk s¤t‚|dk s°t‚|} n4x.t|jƒD] \}}|jtj krØPt |ƒsÂPqÂW|} |dk�rt tj t tjdƒt tj|d d �gƒ} nŽt|t tj|d d �gƒ} |d k�r¤t tj t tjt tjd ƒt tjt tjd ƒt tjd ƒgƒt tjt tjdƒt tjdƒgƒgƒgƒ} | tƒg} ng} | tƒg}|j| j}d|j| _| | t tj ||d �¡t| ƒdk�r| | dt tj | ƒ¡dS)aÍWorks like `does_tree_import` but adds an import statement at the top if it was not imported (but below any __future__ imports) and below any comments such as shebang lines). Based on lib2to3.fixer_util.touch_import() Calling this multiple times adds the imports in reverse order. Also adds "standard_library.install_aliases()" after "from future import standard_library". This should probably be factored into another function. NF)Úabsolute_importÚdivisionÚprint_functionÚunicode_literalsr\T)NNrrArC)r$Zstandard_libraryÚ.Zinstall_aliasesú(ú)r/r)rrr=r<r_rKrJr1rrNr[r rErr r`rZpowerÚtrailerÚDOTÚLPARÚRPARrr$rar)rFZname_to_importr5rcr!rVÚstartÚendrdZidx2rhrfZ install_hooksZchildren_hooksZchildren_importZ old_prefixrrrÚtouch_import_topMsf               r€cCsX|}|jtjkr|jstƒS|jd}|jtjkrRt|jddƒrR|jdjdksXtƒS|jdjtj krv|jd}n |jd}|jtj kròtƒ}xZ|jD]P}|jtj kr¸|  |j¡qš|jtj krš|jd}|jtj ksÞt‚|  |j¡qšW|S|jtj k�r(|jd}|jtj k�st‚t|jgƒS|jtj k�rBt|jgƒSd�sTtd|ƒ‚d S) zZIf this is a future import, return set of symbols that are imported, else return None.rrr4r\érFzstrange import: %sN)r1rrNr<r8Ú import_fromÚhasattrr4r r|Zimport_as_namesr`ÚaddrUrJ)r5ZsavenodeÚresultÚnrrrr_°s8            r_z ^#!.*pythonz^#.*coding[:=]\s*([-\w.]+)cCstt t|j¡ƒS)zÍ Comments are prefixes for Leaf nodes. Returns whether the given node has a prefix that looks like a shebang line or an encoding line: #!/usr/bin/env python #!/usr/bin/python3 )ÚboolÚreÚmatchÚ SHEBANG_REGEXr$)r5rrrr]Þsr]cCstt t|j¡ƒS)a Comments are prefixes for Leaf nodes. Returns whether the given node has a prefix that looks like an encoding line: # coding: utf-8 # encoding: utf-8 # -*- coding: -*- # vim: set fileencoding= : )r‡rˆr‰ÚENCODING_REGEXr$)r5rrrr^és r^cCsHt|ƒdkst‚t|ƒdkr2|\}}|tƒ|g}n|}tt|ƒ||d�S)zö Example: >>> wrap_in_fn_call("oldstr", (arg,)) oldstr(arg) >>> wrap_in_fn_call("olddiv", (arg1, arg2)) olddiv(arg1, arg2) >>> wrap_in_fn_call("olddiv", [arg1, comma, arg2, comma, arg3]) olddiv(arg1, arg2, arg3) rrl)r$)rrJrr r)Zfn_nameÚargsr$Zexpr1Zexpr2ZnewargsrrrÚwrap_in_fn_callös  r�)N)N)N)NN)N)N)4Ú__doc__Zlib2to3.fixer_utilrrrrrrZlib2to3.pytreerr Zlib2to3.pygramr rr r r rrrˆr"r&r(r+r.r6r;r@rHZif_stmtZ while_stmtZfor_stmtZtry_stmtZ with_stmtrOrEr‚rIrTrYr[rgrirqrrr€r_rŠr‹r]r^r�rrrrÚ s>   "      ; ( c*