B A[VD@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~dkr 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).0f)fixG/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.) startswithlen ValueErrorjoin)rZ avail_fixesfoundr)rrcanonical_fix_names     r"cCsttjd|dS)N*)prefix)rr STAR)r$rrrStar6sr&cCsttjd|dS)Nz**)r$)rr DOUBLESTAR)r$rrr DoubleStar9sr(cCsttjd|dS)N-)r$)rr MINUS)r$rrrMinus<sr+cCs2g}x"|D]}|||tq 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) parenttypersuiter INDENTvalueZ 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)rirrrrisz#indentation_step..z N)rsetZ pre_ordermin)r5rZ all_indentsrrrindentation_step`s r;cCsx|jD]}|jtjkrdSqWx,t|jD]\}}|jtjkr,Pq,Wtdttjt 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_noderrrsuitifyps   & r@cCsN|dkr d}td|d|g}|dk rB|tdddt|ddgttj|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 )rextendr r import_name)packageas_namer$r<rrr NameImportsrHccs|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}qW|j}|j}|dkrdSxF|jt kr|jtj kr|V|j}|dkr|j}|j}|dkrPqWdS)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_stmtsAssertionError next_siblingr SEMINEWLINEr0r simple_stmt_compound_stmtsr2)r5testZnxtr0contextcprrrimport_binding_scopesB        rTcCsDt|}tddd}t|dd}ttj|||g}|dk r@||_|S)NrBrC)r$)rr rimport_as_namer$)namerGr$new_nameZnew_asZ new_as_namenew_noderrr ImportAsNames  rYcCs,|jtjko*t|jdko*|jdjtjkS)z< Returns True if the node appears to be a docstring r)r1rrNrr<r STRING)r5rrr is_docstrings r[cCst|}td||rdSd}xNt|jD]@\}}t|s@t|rD|}t|rNq(t|}|s\P||kr(dSq(Wtdt t j |ddg}|dkr|dkr|jdj |_ d|jd_ |t g}||ttj|dS)z This seems to work __future__NrC)r$rr/)rrr=r<is_shebang_commentis_encoding_commentr[check_future_importrrr NAMEr$r insert_childr rrN)featurer5rootZshebang_encoding_idxidxnamesimport_r<rrr future_imports(   rgc Cst|}td||rdSd}xDt|jD]6\}}|jtjkr(|jr(|jdjtjkr(|d}Pq(Wx>|j|dD](}|jtj kr|d7}qr|j }d|_ PqrWd}t dt tj |ddg}|tg}||ttj||ddS)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<rrrfuture_import2s(   ricCsdd|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|] }|dfqS)Nr)rkrrrr4srr) dictr=r1rZargumentr<r EQUALr4)ZarglistschemeZ ret_mappingr7argZslotrrr parse_args.s  rqcCs |jtjko|jot|jdS)Nr)r1rrNr<r)r5rrris_import_stmtHsrrc Cs t|}t|||rdSd}xdD]}td||r"d}Pq"W|rd\}}xNt|jD]@\}}t|rT|}|} x$|r|j}| d7} t|sn| }PqnWPqTW|dk st|dk st|} n4x.t|jD] \}}|jtj krPt |sPqW|} |dkrt tj t tjdt tj|d d g} nt|t tj|d d g} |d krt tj t tjt tjd t tjt tjd t tjd gt tjt tjdt tjdggg} | 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_literalsr\T)NNrrArC)r$Zstandard_library.Zinstall_aliases()r/r)rrr=r<r_rKrJr1rrNr[r rErr r`rZpowertrailerDOTLPARRPARrr$rar)rFZname_to_importr5rcr!rVstartendrdZidx2rhrfZ install_hooksZchildren_hooksZchildren_importZ old_prefixrrrtouch_import_topMsf               rcCsX|}|jtjkr|jstS|jd}|jtjkrRt|jddrR|jdjdksXtS|jdjtj krv|jd}n |jd}|jtj krt}xZ|jD]P}|jtj kr| |jq|jtj kr|jd}|jtj kst| |jqW|S|jtj kr(|jd}|jtj kstt|jgS|jtj krBt|jgSdsTtd|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_fromhasattrr4r r|Zimport_as_namesr`addrUrJ)r5Zsavenoderesultnrrrr_s8            r_z ^#!.*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$)r5rrrr]sr]cCsttt|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$)r5rrrr^s r^cCsHt|dkstt|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) rrl)r$)rrJrr r)Zfn_nameargsr$Zexpr1Zexpr2Znewargsrrrwrap_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+r.r6r;r@rHZif_stmtZ while_stmtZfor_stmtZtry_stmtZ with_stmtrOrErrIrTrYr[rgrirqrrrr_rrr]r^rrrrr s>   "      ; ( c*