3 \g; @sdZddlmZddlmZmZddlmZddl m Z ddZ dd Z d d Z d d ZdWddZddZddZddZe e fddZdXddZddZddZdYdd Zd!d"ZdZd#d$Zd[d%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2d3d4d5d6d7d8d9d:h Z d;d<Z!d=a"d>a#d?a$d@a%dAdBZ&dCdDZ'dEdFZ(dGdHZ)dIdJZ*dKdLZ+dMdNZ,dOdPZ-ej.ej/hZ0d\dQdRZ1ej/ej.ej2hZ3dSdTZ4d]dUdVZ5dS)^z1Utility functions, node construction macros, etc.)token)LeafNode)python_symbols)patcompcCsttj|ttjd|gS)N=)rsymsZargumentrrEQUAL)keywordvaluer "/usr/lib64/python3.6/fixer_util.py KeywordArgsrcCs ttjdS)N()rrLPARr r r r LParensrcCs ttjdS)N))rrRPARr r r r RParensrcCsHt|ts|g}t|ts&d|_|g}ttj|ttjdddg|S)zBuild an assignment statement r)prefix) isinstancelistrrratomrrr )targetsourcer r r Assigns  rNcCsttj||dS)zReturn a NAME leaf)r)rrNAME)namerr r r Name$srcCs|ttjt|ggS)zA node tuple for obj.attr)rrtrailerDot)objattrr r r Attr(sr$cCs ttjdS)z A comma leaf,)rrCOMMAr r r r Comma,sr'cCs ttjdS)zA period (.) leaf.)rrDOTr r r r r!0sr!cCs4ttj|j|jg}|r0|jdttj||S)z-A parenthesised argument list, used by Call()r)rrr clone insert_childarglist)argsZlparenZrparennoder r r ArgList4sr/cCs&ttj|t|g}|dk r"||_|S)zA function callN)rrpowerr/r)Z func_namer-rr.r r r Call;sr1cCs ttjdS)zA newline literal )rrNEWLINEr r r r NewlineBsr4cCs ttjdS)z A blank line)rrr3r r r r BlankLineFsr6cCsttj||dS)N)r)rrNUMBER)nrr r r NumberJsr9cCs"ttjttjd|ttjdgS)zA numeric or string subscript[])rrr rrLBRACERBRACE)Z index_noder r r SubscriptMsr>cCsttj||dS)z A string leaf)r)rrSTRING)stringrr r r StringSsrAc Csd|_d|_d|_ttjd}d|_ttjd}d|_||||g}|rtd|_ttjd}d|_|jttj||gttj|ttj |g}ttj ttj d|ttj dgS)zuA list comprehension of the form [xp for fp in it if test]. If test is None, the "if test" part is omitted. r5rforinifr:r;) rrrrappendrrZcomp_ifZ listmakerZcomp_forrr<r=) ZxpfpitZtestZfor_leafZin_leafZ inner_argsZif_leafinnerr r r ListCompWs$     rIcCsZx|D] }|jqWttjdttj|ddttjdddttj|g}ttj|}|S)zO Return an import statement in the form: from package import name_leafsfromr)rimport)removerrrrrimport_as_names import_from)Z package_nameZ name_leafsZleafchildrenimpr r r FromImportos    rQc Cs|dj}|jtjkr"|j}nttj|jg}|d}|rNdd|D}ttjtt|dt|dttj|dj||djgg|}|j |_ |S) zfReturns an import statement and calls a method of the module: import module module.name()r"aftercSsg|] }|jqSr )r*).0r8r r r sz!ImportAndCall..rZlparZrpar) r*typerr,rr0r$rr r)r.resultsnamesr"Z newarglistrRnewr r r ImportAndCalls   DrZcCst|tr |jttgkr dSt|tot|jdkot|jdtot|jdtot|jdto|jdjdko|jdjdkS)z(Does the node represent a tuple literal?TrUrrr)rrrOrrlenrr )r.r r r is_tuples r^cCsXt|toVt|jdkoVt|jdtoVt|jdtoV|jdjdkoV|jdjdkS)z'Does the node represent a list literal?rrUr:r;r_)rrr]rOrr )r.r r r is_lists  r`cCsttjt|tgS)N)rrrrr)r.r r r parenthesizesrasortedrsetanyalltuplesumminmax enumerateccs(t||}x|r"|Vt||}q WdS)alFollow an attribute chain. If you have a chain of objects where a.foo -> b, b.foo-> c, etc, use this to iterate over all objects in the chain. Iteration is terminated by getattr(x, attr) is None. Args: obj: the starting object attr: the name of the chaining attribute Yields: Each successive object in the chain. N)getattr)r"r#nextr r r attr_chains rmzefor_stmt< 'for' any 'in' node=any ':' any* > | comp_for< 'for' any 'in' node=any any* > z power< ( 'iter' | 'list' | 'tuple' | 'sorted' | 'set' | 'sum' | 'any' | 'all' | 'enumerate' | (any* trailer< '.' 'join' >) ) trailer< '(' node=any ')' > any* > z` power< ( 'sorted' | 'enumerate' ) trailer< '(' arglist ')' > any* > FcCsrts&tjtatjtatjtadatttg}x|jtjkr|S|j}|jd}|_ttj|g}||_|S)N)rVrr|r*rnr)r.rnr|r r r make_suites rcCs(x"|jtjkr"|j}|stdqW|S)zFind the top level namespace.z,root found before file_input node was found.)rVrZ file_inputrn ValueError)r.r r r find_root&s  rcCst|t||}t|S)z Returns true if name is imported from package at the top level of the tree which node belongs to. To cover the case of an import like 'import foo', use None for the package and 'foo' for the name. ) find_bindingrbool)packagerr.Zbindingr r r does_tree_import/srcCs|jtjtjfkS)z0Returns true if the node is an import statement.)rVr import_namerN)r.r r r is_import7src Cs4dd}t|}t|||r dSd}}xTt|jD]F\}}||sFq4x(t|j|dD]\}}||sZPqZW||}Pq4W|dkrxDt|jD]6\}}|jtjkr|jr|jdjtjkr|d}PqW|dkrt tj t tj dt tj |ddg} nt |t tj |ddg} | tg} |j|t tj| dS) z\ Works like `does_tree_import` but adds an import statement if it was not imported. cSs |jtjko|jot|jdS)NrU)rVr simple_stmtrOr)r.r r r is_import_stmt>sz$touch_import..is_import_stmtNrUrrKr)r)rrrjrOrVrrrr?rrrrrQr4r+) rrr.rrootZ insert_posoffsetidxZnode2import_rOr r r touch_import;s4   rcCsx|jD]}d}|jtjkrVt||jdr4|St|t|jd|}|rR|}n4|jtjtjfkrt|t|jd |}|r|}n|jtj krt|t|jd|}|r|}nXxt |jddD]@\}}|jt j ko|j dkrt|t|j|d|}|r|}qWnx|jtkr6|jdj |kr6|}nTt|||rJ|}n@|jtjkrft|||}n$|jtjkrt||jdr|}|r |s|St|r |Sq WdS) z Returns the node which binds variable name, otherwise None. If optional argument package is supplied, only imports will be returned. See test cases for examples.Nrr\r[:rUr_r_)rOrVrZfor_stmt_findrrZif_stmtZ while_stmtZtry_stmtrjrCOLONr _def_syms_is_import_bindingrryr)rr.rchildZretr8iZkidr r r risH  rcCsX|g}xL|rR|j}|jdkr6|jtkr6|j|jq|jtjkr|j|kr|SqWdS)N)poprV _block_symsextendrOrrr )rr.Znodesr r r rsrcCs|jtjkr| r|jd}|jtjkrvx|jD]@}|jtjkrV|jdj|krp|Sq0|jtjkr0|j|kr0|Sq0WnL|jtjkr|jd}|jtjkr|j|kr|Sn|jtjkr|j|kr|Sn|jtj kr|rt |jdj |krdS|jd}|rt d|rdS|jtj kr.t ||r.|S|jtjkrf|jd}|jtjkr|j|kr|Sn6|jtjkr|j|kr|S|r|jtjkr|SdS)z Will reuturn node if node will import name, or node will import * from package. None is returned otherwise. See test cases for examples. rr\Nr[asr_)rVrrrOZdotted_as_namesZdotted_as_namer rrrNstrstriprrMZimport_as_nameSTAR)r.rrrPrZlastr8r r r rs@         r)N)NN)N)N)N)N)N)6__doc__Zpgen2rZpytreerrZpygramrrr5rrrrrrr$r'r!r/r1r4r6r9r>rArIrQrZr^r`raZconsuming_callsrmrprqrrrorvr{rrrrrrrxrwrrr rrrr r r r sZ            -  *