B ,]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_fix_Ncs g|]}|dr|qS)zfix_{0})endswithformat).0f)fix=/tmp/pip-target-9_2btsuh/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 -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_leafsleafrrr commatize?s   r0cCs|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 INDENTvalue prev_siblingr%)noderrr indentationKs    r9cCs2t|}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)r3r r5r6)rirrrrisz#indentation_step..z N)rset pre_ordermin)r8rZ 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 ':'!rr1)childrenr3rr4 enumerater COLONr r rrr5r9r?remover% append_child)r2r8r:r4Zone_noderrrsuitifyps   & rEcCsN|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 ] Nr1import)r%as )rextendr r import_name)packageas_namer%r@rrr NameImportsrMccs|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) r3 _import_stmtsAssertionError next_siblingr SEMINEWLINEr2r simple_stmt_compound_stmtsr4)r8testZnxtr2contextcprrrimport_binding_scopesB        rYcCsDt|}tddd}t|dd}ttj|||g}|dk r@||_|S)NrGrH)r%)rr rimport_as_namer%)namerLr%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)r3rrSrr@r STRING)r8rrr 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__NrH)r%rr1)rrrAr@is_shebang_commentis_encoding_commentr`check_future_importrrr NAMEr%r insert_childr rrS)featurer8rootZshebang_encoding_idxidxnamesimport_r@rrr future_imports(   rlc 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 ... raNrrr1rH)r%)rrrAr@r3rrSr r_rRr%rrrerrfr ) rgr8rh insert_posriZ thing_afterr%rkr@rrrfuture_import2s(   rncCsdd|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)r3r COMMA)rr:rrrr2szparse_args..cSsg|] }|dfqS)Nr)rkrrrr4srr) dictrAr3rargumentr@r EQUALr6)arglistschemeZ ret_mappingr:argZslotrrr parse_args.s  rxcCs |jtjko|jot|jdS)Nr)r3rrSr@r)r8rrris_import_stmtHsryc 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_literalsraT)NNrrFrH)r%Zstandard_library.Zinstall_aliases()r1r)rrrAr@rdrPrOr3rrSr`r rJrr rerpowertrailerDOTLPARRPARrr%rfr)rKZname_to_importr8rhr"r[startendriZidx2rmrkZ 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.rrr6rarFzstrange import: %sN)r3rrSr@r; import_fromhasattrr6r rimport_as_namesreaddrZrO)r8Zsavenoderesultnrrrrds8            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|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) rrq)r%)rrOrr 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,r0r9r?rErMif_stmt while_stmtfor_stmttry_stmt with_stmtrTrJrrNrYr^r`rlrnrxryrrdrrrbrcrrrrr s>   "      ; ( c*