o ,]VD@s\dZddlmZmZmZmZmZmZddlm Z m Z ddl m Z mZddl mZddlm Z mZmZm Z mZmZddlZdd Zd4d d Zd4d d Zd4ddZddZddZddZddZd5ddZe je je je j e j!fZ"e j#e j$fZ%ddZ&d4ddZ'ddZ(d d!Z)d"d#Z*d$d%Z+d&d'Z,d(d)Z-d*d+Z.d,Z/d-Z0d.d/Z1d0d1Z2d4d2d3Z3dS)6z 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 CallNamesymsrNumberNcsxdvrSdrddfdd|D}t|dkr.tdd d d |Dt|d kr8td |d S)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_fix_Ncs g|] }|dr|qS)zfix_{0})endswithformat).0ffix8/usr/lib/python3/dist-packages/libfuturize/fixer_util.py (s z&canonical_fix_name..zOAmbiguous fixer name. Choose a fully qualified module name instead from these:  css|]}d|VqdS)z Nr)rmyfrrr -sz%canonical_fix_name..rz1Unknown fixer. Use --list-fixes or -l for a list.) startswithlen ValueErrorjoin)r avail_fixesfoundrrrcanonical_fix_names     r&cCttjd|dS)N*prefix)rr STARr)rrrStar6r,cCr')Nz**r))rr DOUBLESTARr)rrr DoubleStar9r-r/cCr')N-r))rr MINUSr)rrrMinus<r-r2cCs.g}|D] }|||tq|d=|S)z{ Accepts/turns: (Name, Name, ..., Name, Name) Returns/into: (Name, Comma, Name, Comma, ..., Name, Comma, Name) )appendr)leafs new_leafsleafrrr commatize?s  r8cCs|jdur|jjtjkr|j}|jdur|jjtjks |jdur"dS|jtjkr+|jS|jdur;|jjtjkr;|jjS|jdurBdS|jS)zf Returns the indentation for this node Iff a node is in a suite, then it has indentation. N) parenttypersuiter INDENTvalue prev_siblingr*noderrr indentationKs   rBcCs.t|}tdd|D}|sdSt|S)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)r;r r=r>rirrrris z#indentation_step..z )rset pre_ordermin)rAr all_indentsrrrindentation_step`s rKcCs|jD] }|jtjkrdSqt|jD] \}}|jtjkr nqtdttjt 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 ':'!rr9)childrenr;rr< enumerater COLONr"r rrr=rBrKremover* append_child)r:rArEr<one_noderrrsuitifyps   & rRcCsN|durd}td|d|g}|dur!|tdddt|ddgttj|S)z Accepts a package (Name node), name to import it as (string), and optional prefix and returns a node: import [as ] Nr9importr)as )rextendr r import_name)packageas_namer*rLrrr NameImports  rZccs(|jtvsJ|j}|jtjkr'|j}|jtjkrn |V|j}|jtjks|j}|jtjks2J|j}|durC|V|j}|dus9|j}|jt vra|}|jdur^|jV|j}|jdusR|j}|j}|durjdS|jt vr|jtj krx|V|j}|dur|j}|j}|durdS|jt vsodSdS)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) r; _import_stmts next_siblingr SEMINEWLINEr:r simple_stmt_compound_stmtsr<)rAtestnxtr:contextcprrrimport_binding_scopesL         rfcCsDt|}tddd}t|dd}ttj|||g}|dur ||_|S)NrTrUr))rr rimport_as_namer*)namerYr*new_namenew_as new_as_namenew_noderrr ImportAsNames  rmcCs,|jtjkot|jdko|jdjtjkS)z< Returns True if the node appears to be a docstring r)r;rr_r!rLr STRINGr@rrr is_docstrings  rocCst|}td||r dSd}t|jD]"\}}t|st|r!|}t|r&qt|}|s.n||vr5dSqtdt t j |ddg}|dkrW|dkrW|jdj |_ d|jd_ |t g}||ttj|dS)z This seems to work __future__NrUr)rr9)rrrMrLis_shebang_commentis_encoding_commentrocheck_future_importrrr NAMEr*r insert_childr rr_)featurerArootshebang_encoding_idxidxnamesimport_rLrrr future_imports*   r|c Cst|}td||r dSd}t|jD]\}}|jtjkr/|jr/|jdjtjkr/|d}nq|j|dD]}|jtj krD|d7}q7|j }d|_ nd}t dt tj |ddg}|tg}||ttj||ddS)zD An alternative to future_import() which might not work ... rpNrrr9rUr))rrrMrLr;rr_r rnr^r*rrrtrrur ) rvrArw insert_posry thing_afterr*r{rLrrrfuture_import2s*   rcCsdd|D}tdd|D}t|D])\}}|jtjkr5|jdjtjkr5|jdj}|jd||<q||}|||<q|S)z/ Parse a list of arguments into a dict cSsg|] }|jtjkr|qSr)r;r COMMArDrrrr2szparse_args..cSsg|]}|dfqSrCr)rkrrrr4srr) dictrMr;rargumentrLr EQUALr>)arglistscheme ret_mappingrEargslotrrr parse_args.s  rcCs |jtjko|jot|jdS)Nr)r;rr_rLrr@rrris_import_stmtHs rc Cst|}t|||r dSd}dD] }td||rd}nq|rXd\}}t|jD] \}}t|rH|}|} |rF|j}| d7} t|sD| }n|s6nq(|dusOJ|dusUJ|} nt|jD]\}}|jtjkrint |sonq]|} |durt tj t t jdt t j|d d g} nFt|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| dSdS)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_literalsrpTNNrrSrUr)standard_library.install_aliases()r9r)rrrMrLrsr\r;rr_ror rWrr rtrpowertrailerDOTLPARRPARrr*rur!)rXname_to_importrArwr%rhstartendryidx2r}r{ install_hookschildren_hookschildren_import old_prefixrrrtouch_import_topMs|            rcCsD|}|jtjkr |jstS|jd}|jtjkr)t|jddr)|jdjdks,tS|jdjtj kr;|jd}n|jd}|jtj krwt}|jD](}|jtj kr[| |jqL|jtj krt|jd}|jtj ksnJ| |jqL|S|jtj kr|jd}|jtj ksJt|jgS|jtj krt|jgSJd|) zZIf this is a future import, return set of symbols that are imported, else return None.rrr>rprFzstrange import: %s)r;rr_rLrF import_fromhasattrr>r rimport_as_namesrtaddrg)rAsavenoderesultnrrrrss<                rsz ^#!.*pythonz^#.*coding[:=]\s*([-\w.]+)cCttt|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*r@rrrrqsrqcCr)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*r@rrrrrs rrcCsHt|dksJt|dkr|\}}|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) rrr))r!rr r)fn_nameargsr*expr1expr2newargsrrrwrap_in_fn_calls  rrCr)4__doc__lib2to3.fixer_utilrrrrrrlib2to3.pytreerr lib2to3.pygramr rr r r rrrr&r,r/r2r8rBrKrRrZif_stmt while_stmtfor_stmttry_stmt with_stmtr`rWrr[rfrmror|rrrrrsrrrqrrrrrrrs@    "      ; ( c*