B /g^g;c @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)Zkeywordvaluer */usr/lib64/python3.7/lib2to3/fixer_util.py KeywordArgsr cC ttjdS)N()rrZLPARr r r r LParenrcCr )N))rrZRPARr r r r RParenrrcCsHt|ts|g}t|ts&d|_|g}ttj|ttjdddg|S)zBuild an assignment statement rprefix) isinstancelistrrratomrrr)ZtargetZsourcer r r Assigns  rNcCttj||dS)zReturn a NAME leafr)rrNAME)namerr r r Name$rcCs|ttjt|ggS)zA node tuple for obj.attr)rrtrailerDot)objattrr r r Attr(rr#cCr )z A comma leafz,)rrCOMMAr r r r Comma,rr%cCr )zA period (.) leafZ.)rrDOTr r r r r 0rr cCs4ttj||g}|r0|dttj||S)z-A parenthesised argument list, used by Call()r)rrrclone 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;sr.cCr )zA newline literalZ rrZNEWLINEr r r r NewlineBrr0cCr )z A blank liner/r r r r BlankLineFrr2cCr)Nr)rrZNUMBER)nrr r r NumberJrr4cCs"ttjttjd|ttjdgS)zA numeric or string subscript[])rrrrrLBRACERBRACE)Z index_noder r r SubscriptMsr9cCr)z A string leafr)rrSTRING)Zstringrr r r StringSrr;c Csd|_d|_d|_ttjd}d|_ttjd}d|_||||g}|rtd|_ttjd}d|_|ttj||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. r1rZforZinZifr5r6) rrrrZappendrrZcomp_ifZ listmakerZcomp_forrr7r8) ZxpZfpZitZtestZfor_leafZin_leafZ inner_argsZif_leafZinnerr r r ListCompWs$     r<cCsZx|D] }|qWttjdttj|ddttjdddttj|g}ttj|}|S)zO Return an import statement in the form: from package import name_leafsZfromrrimport)Zremoverrrrrimport_as_names import_from)Z package_nameZ name_leafsZleafchildrenimpr r r FromImportos    rBc Cs|d}|jtjkr"|}nttj|g}|d}|rNdd|D}ttjtt|dt|dttj|d||dgg|}|j |_ |S) zfReturns an import statement and calls a method of the module: import module module.name()r!aftercSsg|] }|qSr )r')Z.0r3r r r z sz!ImportAndCall..rZlparZrpar) r'typerr)rr-r#rrr)r+resultsZnamesr!Z newarglistrCZnewr r r ImportAndCalls   DrGcCst|tr |jttgkr dSt|tot|jdkot|jdtot|jdtot|jdto|jdjdko|jdjdkS)z(Does the node represent a tuple literal?TrDrrr)rrr@rrlenrr r+r r r is_tuples rLcCsXt|toVt|jdkoVt|jdtoVt|jdtoV|jdjdkoV|jdjdkS)z'Does the node represent a list literal?rrDr5r6)rrrJr@rr rKr r r is_lists  rNcCsttjt|tgSN)rrrrrrKr r r parenthesizerrPZsortedrZsetZanyZallZtupleZsumZminZmax 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)Zgetattr)r!r"Znextr r r attr_chains rRzefor_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&ttattattadatttg}x|jtjkr|S|}|jd}|_ttj|g}||_|SrO)rErr]r'rSr)r+rSr]r r r make_suites r_cCs(x"|jtjkr"|j}|stdqW|S)zFind the top level namespace.z,root found before file_input node was found.)rErZ file_inputrSZ ValueErrorrKr r r find_root&s  r`cCst|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_bindingr`Zbool)packagerr+Zbindingr r r does_tree_import/srccCs|jtjtjfkS)z0Returns true if the node is an import statement.)rEr import_namer?rKr r r is_import7rrec 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} ||t tj| dS) z\ Works like `does_tree_import` but adds an import statement if it was not imported. cSs |jtjko|jot|jdS)NrD)rEr simple_stmtr@rerKr r r is_import_stmt>sz$touch_import..is_import_stmtNrDrr=rr)r`rcrQr@rErrfrr:rrdrrrBr0r() rbrr+rgZrootZ insert_posZoffsetZidxZnode2Zimport_r@r r r touch_import;s4   rhcCsx|jD]}d}|jtjkrVt||jdr4|St|t|jd|}|rR|}n4|jtjtjfkrt|t|jd|}|r|}n|jtj krt|t|jd|}|r|}nXxt |jddD]@\}}|jt j kr|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.NrrMrIrHz:irD)r@rErZfor_stmt_findrar_Zif_stmtZ while_stmtZtry_stmtrQrZCOLONr _def_syms_is_import_bindingrfr[re)rr+rbchildZretr3ZiZkidr r r raisH  racCsX|g}xL|rR|}|jdkr6|jtkr6||jq|jtjkr|j|kr|SqWdS)Ni)ZpoprE _block_symsZextendr@rrr )rr+Znodesr r r risricCs|jtjkr|s|jd}|jtjkrtx|jD]@}|jtjkrT|jdj|krn|Sq.|jtjkr.|j|kr.|Sq.WnL|jtjkr|jd}|jtjkr|j|kr|Sn|jtjkr|j|kr|Sn|jtj kr|rt |jd |krdS|jd}|rt d|rdS|jtj kr,t ||r,|S|jtjkrd|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. rrIrMNrHZas)rErrdr@Zdotted_as_namesZdotted_as_namer rrr?ZstrZstriprir>Zimport_as_nameZSTAR)r+rrbrArlZlastr3r r r rks@         rkrO)NNrOrOrOrOrO)6Z__doc__Zpgen2rZpytreerrZpygramrrr1rr rrrrr#r%r r,r.r0r2r4r9r;r<rBrGrLrNrPZconsuming_callsrRrUrVrWrTrXr\r^r_r`rcrerhrZrYrjrarrmrirkr r r r ZsZ            -  *