a 97aVD@s\dZddlmZmZmZmZmZmZddlm Z m Z ddl m Z mZddl mZddlm Z mZmZm Z mZmZddlZdd Zd4d d Zd5d d Zd6ddZddZddZddZddZd7ddZe je je je j e j!fZ"e j#e j$fZ%ddZ&d8ddZ'ddZ(d d!Z)d"d#Z*d$d%Z+d&d'Z,d(d)Z-d*d+Z.d,Z/d-Z0d.d/Z1d0d1Z2d9d2d3Z3dS):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) ) FromImportNewline is_import find_rootdoes_tree_importComma)LeafNode)python_symbolspython_grammar)token)r CallNamesymsrNumberNcs~dvr Sdr"ddfdd|D}t|dkr^tdd d d |Dnt|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|]}|dr|qS)zfix_{0})endswithformat).0ffixq/private/var/folders/s6/9n5zrl012gv99k63s4q6ccsd4s6mqz/T/pip-target-f5cq3f2q/lib/python/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 -z%canonical_fix_name..rz1Unknown fixer. Use --list-fixes or -l for a list.) startswithlen ValueErrorjoin)rZ avail_fixesfoundrrrcanonical_fix_names     r$cCsttjd|dS)N*prefix)rr STARr&rrrStar6sr)cCsttjd|dS)Nz**r&)rr DOUBLESTARr&rrr DoubleStar9sr+cCsttjd|dS)N-r&)rr MINUSr&rrrMinus<sr.cCs.g}|D]}|||tq|d=|S)z{ Accepts/turns: (Name, Name, ..., Name, Name) Returns/into: (Name, Comma, Name, Comma, ..., Name, Comma, Name) )appendr)ZleafsZ new_leafsZleafrrr commatize?s  r1cCsx|jdur |jjtjkr |j}q|jdur.dS|jtjkr@|jS|jdur`|jjtjkr`|jjS|jdurndS|jSdS)zf Returns the indentation for this node Iff a node is in a suite, then it has indentation. N) parenttypersuiter INDENTvalueZ prev_siblingr'noderrr indentationKs   r:cCs2t|}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|jVqdSN)r4r r6r7rirrrrirz#indentation_step..z N)rsetZ pre_ordermin)r9rZ all_indentsrrrindentation_step`s rAcCs|jD]}|jtjkrdSqt|jD]\}}|jtjkr(qJq(tdttjt 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 ':'!rr2)childrenr4rr5 enumerater COLONr!r rrr6r:rAremover'Z append_child)r3r9r=r5Zone_noderrrsuitifyps   & rFcCsN|dur d}td|d|g}|durB|tdddt|ddgttj|S)z Accepts a package (Name node), name to import it as (string), and optional prefix and returns a node: import [as ] Nr2importr&as )rextendr r import_name)packageas_namer'rBrrr NameImports rNccs|jtvsJ|j}|jtjkrD|j}|jtjkr6qDn|V|j}q|j}|jtjksZJ|j}|durv|V|j}q`|j}|jt vr|}|jdur|jV|j}q|j}|j}|durdS|jt vr|jtj kr|V|j}|dur|j}|j}|durqqdS)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) r4 _import_stmts next_siblingr SEMINEWLINEr3r simple_stmt_compound_stmtsr5)r9testZnxtr3contextcprrrimport_binding_scopesB      rYcCsDt|}tddd}t|dd}ttj|||g}|dur@||_|S)NrHrIr&)rr rimport_as_namer')namerMr'new_nameZnew_asZ new_as_namenew_noderrr ImportAsNames  r^cCs,|jtjko*t|jdko*|jdjtjkS)z< Returns True if the node appears to be a docstring r)r4rrSr rBr STRINGr8rrr is_docstrings   r`cCst|}td||rdSd}t|jD]D\}}t|s>t|rB|}t|rLq&t|}|s\ql||vr&dSq&tdt t j |ddg}|dkr|dkr|jdj |_ d|jd_ |t g}||ttj|dS)z This seems to work __future__NrIr&rr2)rrrCrBis_shebang_commentis_encoding_commentr`check_future_importrrr NAMEr'r insert_childr rrS)featurer9rootZshebang_encoding_idxidxnamesimport_rBrrr future_imports(   rlc Cst|}td||rdSd}t|jD]8\}}|jtjkr&|jr&|jdjtjkr&|d}q`q&|j|dD]*}|jtj kr|d7}qn|j }d|_ qqnd}t dt tj |ddg}|tg}||ttj||ddS)zD An alternative to future_import() which might not work ... raNrrr2rIr&)rrrCrBr4rrSr r_rRr'rrrerrfr ) rgr9rh insert_posriZ thing_afterr'rkrBrrrfuture_import2s*   rncCsdd|D}tdd|D}t|D]R\}}|jtjkrj|jdjtjkrj|jdj}|jd||<q(||}|||<q(|S)z/ Parse a list of arguments into a dict cSsg|]}|jtjkr|qSr)r4r COMMAr<rrrr2rzparse_args..cSsg|] }|dfqSr;r)rkrrrr4rrr) dictrCr4rZargumentrBr EQUALr7)ZarglistschemeZ ret_mappingr=argZslotrrr parse_args.s  rvcCs |jtjko|jot|jdS)Nr)r4rrSrBrr8rrris_import_stmtHs rwc Cst|}t|||rdSd}dD]}td||r d}q:q |rd\}}t|jD]>\}}t|rP|}|} |r|j}| d7} t|sh| }qqhqqP|dusJ|dusJ|} n4t|jD]$\}}|jtjkrqt |sqq|} |durt tj t t jdt t j|d d g} nt|t t j|d d g} |d krt tjt tjt t jd t tjt t jd t t jd gt tjt t jdt t jdggg} | tg} ng} | tg}|j| j}d|j| _|| t tj||d t| dkr|| dt tj| dS)aWorks 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_importdivisionprint_functionunicode_literalsraT)NNrrGrIr&Zstandard_library.Zinstall_aliases()r2r)rrrCrBrdrPr4rrSr`r rKrr rerpowertrailerDOTLPARRPARrr'rfr )rLZname_to_importr9rhr#r[startendriZidx2rmrkZ install_hooksZchildren_hooksZchildren_importZ old_prefixrrrtouch_import_topMsr                rcCsT|}|jtjkr|jstS|jd}|jtjkrRt|jddrR|jdjdksXtS|jdjtj krv|jd}n |jd}|jtj krt}|jD]P}|jtj kr| |jq|jtj kr|jd}|jtj ksJ| |jq|S|jtj kr$|jd}|jtj ksJt|jgS|jtj kr>t|jgSdsPJd|d S) zZIf this is a future import, return set of symbols that are imported, else return None.rrr7rarFzstrange import: %sN)r4rrSrBr> import_fromhasattrr7r rZimport_as_namesreaddrZ)r9Zsavenoderesultnrrrrds<            rdz ^#!.*pythonz^#.*coding[:=]\s*([-\w.]+)cCsttt|jS)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 )boolrematch SHEBANG_REGEXr'r8rrrrbsrbcCsttt|jS)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= : )rrrENCODING_REGEXr'r8rrrrcs rccCsHt|dksJt|dkr2|\}}|t|g}n|}tt|||dS)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) rrqr&)r rr r)fn_nameargsr'expr1Zexpr2Znewargsrrrwrap_in_fn_calls  r)N)N)N)NN)N)N)4__doc__Zlib2to3.fixer_utilrrrrrrZlib2to3.pytreerr Zlib2to3.pygramr rr r r rrrr$r)r+r.r1r:rArFrNZif_stmtZ while_stmtZfor_stmtZtry_stmtZ with_stmtrTrKrrOrYr^r`rlrnrvrwrrdrrrbrcrrrrrs>   "      ; ( c*