qBFjCTUddlZddlZddlZddlZddlZddlZddlmZddlmZm Z m Z ddl m Z ddl mZmZmZmZmZmZmZmZmZmZmZmZer%ddlmZGdd e ZeeefZejZd ZGd d ej d d Z!d2dZ"d2dZ#dZ$dZ%dZ&d3dZ'dej()DZ*d3dZ+dej()DZ,dej()DhdzZ-dZ.dZ/dZ0dZ1dZ2ej3fZ4eedfe5d < dd!l6m7Z7e4e7fz Z4n #e8$rYnwxYwd"Z9d#Z:d$Z;d%ZZ?d'Z@d3d(ZAd)ZBGd*d+ZCd,ZDd-ZEd.ZFe d/d0ZGd1ZHdS)4N)ABCMeta)ModuleexprAST) lru_cache) CallableDictIterableIteratorListOptionalTupleUnioncastAny TYPE_CHECKINGType)NodeNGc"eZdZdZdZdZdZdZdS) EnhancedASTNr)__name__ __module__ __qualname__ first_token last_tokenlineno end_linenoend_col_offsetYsw UHg . .+ *7####SZZZZ k!nnnek!nq((* + ++++r!cL|tjtjtjfvS)zS These are considered non-coding tokens, as they don't affect the syntax tree. )r&NLCOMMENTENCODING) token_types r"is_non_coding_tokenrDes %-@ @@r!ctjttgtft j|jS)z; Generates standard library tokens for the given code. )tokenizegenerate_tokensrrr<ioStringIOreadline)texts r"rGrGms5  !$xC'8"+d:K:K:T"U"U V VVr!c>t|drtntS)z Returns a function which yields all direct children of a AST node, skipping children that are singleton nodes. The function depends on whether ``node`` is from ``ast`` or from the ``astroid`` module. get_children)hasattriter_children_astroiditer_children_astnodes r"iter_children_funcrSxs #*$"?"? V  EVVr!FcP|st|rgS|Sr0) is_joined_strrM)rRinclude_joined_strs r"rOrOs0  d 3 3 I    r!c h|]c\}}t|tt|tjtjtjtjtjfa|dSr ) isinstancer1 issubclassast expr_contextboolopoperatorunaryopcmpop.0ncs r" rdskcccDAqJq$4G4GcS-sz3<VYV_`aacacccr!c#K|st|rdSt|tjr,t |j|jD]\}}||V|VdStj|D]}|jtvr|VdSr0) rUrXrZr zipkeysvaluesiter_child_nodes __class__ SINGLETONS)rRrVkeyvaluechilds r"rPrPs  d 3 3  Fch DIt{33 e  kkkk F#D))e j(( kkk r!cvh|]6\}}t|tt|tj4|7Sr )rXr1rYrZstmtr`s r"rdrdsVHHH$!Q!!T**H/9!SX/F/FHAHHHr!cvh|]6\}}t|tt|tj4|7Sr )rXr1rYrZrr`s r"rdrdsVHHH41a!!T**H/9!SX/F/FHQHHHr!>ConstDelAttrDelName AssignAttr AssignNamec(|jjtvS)z+Returns whether node is an expression node.)rjrexpr_class_namesrQs r"is_exprry  $4 44r!c(|jjtvS)z)Returns whether node is a statement node.)rjrstmt_class_namesrQs r"is_stmtr}rzr!c"|jjdkS)z&Returns whether node is a module node.rrjrrQs r" is_modulers  H ,,r!c"|jjdkS)zFReturns whether node is a JoinedStr node, used to represent f-strings. JoinedStrrrQs r"rUrUs  K //r!c"|jjdkS)zSReturns whether node is an `Expr` node, which is a statement that is an expression.ExprrrQs r" is_expr_stmtrs  F **r!.CONSTANT_CLASSES)rrc,t|tS)z(Returns whether node is a Constant node.)rXrrQs r" is_constantrs D* + ++r!c<t|o |jtuS)z)Returns whether node is an Ellipsis node.)rrmEllipsisrQs r" is_ellipsisrs T   5tzX55r!c"|jjdkS)z2Returns whether node is a starred expression node.StarredrrQs r" is_starredrs  I --r!c |jjdvpN|jjdko>tttt t j|jS)z?Returns whether node represents a slice, e.g. `1:2` in `x[1:2]`)SliceExtSlicer) rjranymapis_slicerrZreltsrQs r"rrsR  n!66 . !W , =#hSY 5 5 :;;<< r!c|jjdko:t|tj o|j|jcxuo |jcxuoduncS)Nr)rjrrXrZrloweruppersteprQs r"is_empty_astroid_slicerse n(8sw'' '8 * 7 7 7 7di 7 7 7 74 7 7 7 7r!c|sd}t|}t}d}|dtfg}|r|\}}} | tur~||vsJ|||||\} } |||| ft |} ||D] } || | | tf!n+|||ttt| }||S)a5 Scans the tree under the node depth-first using an explicit stack. It avoids implicit recursion via the function call stack to avoid hitting 'maximum recursion depth exceeded' error. It calls ``previsit()`` and ``postvisit()`` as follows: * ``previsit(node, par_value)`` - should return ``(par_value, value)`` ``par_value`` is as returned from ``previsit()`` of the parent. * ``postvisit(node, par_value, value)`` - should return ``value`` ``par_value`` is as returned from ``previsit()`` of the parent, and ``value`` is as returned from ``previsit()`` of this node itself. The return ``value`` is ignored except the one for the root node, which is returned from the overall ``visit_tree()`` call. For the initial node, ``par_value`` is None. ``postvisit`` may be None. cdSr0r )rRpvaluerms r"zvisit_tree..sDr!N) rSset _PREVISITpopaddappendleninsertrr r.)rRprevisit postvisit iter_childrendoneretstackcurrent par_valuermr post_valueinsrbs r" visit_treers6$ 100I$T**- $ # $ " #% H % GY  D  hhw#8GY77fj llGY 3444 JJc}W%%22! S1fi011112 Igy$x*F*F G Gc H *r!c#$Kt|}t}|g}|rk|}||vsJ|||Vt |}|||D]}||||idSdS)a1 Recursively yield all descendant nodes in the tree starting at ``node`` (including ``node`` itself), using depth-first pre-order traversal (yieling parents before their children). This is similar to ``ast.walk()``, but with a different order, and it works for both ``ast`` and ``astroid`` trees. Also, as ``iter_children()``, it skips singleton nodes generated by ``ast``. By default, ``JoinedStr`` (f-string) nodes and their contents are skipped because they previously couldn't be handled. Set ``include_joined_str`` to True to include them. N)rSrrrrr)rRrVrrrrrrcs r"walkr)s%T**- $ &% iikkG $    HHW MMM e**C ]7$6 7 7 ll3      r!cd}g}t|D]:\}}}|||||||};|||dd|S)ah Replaces multiple slices of text with new values. This is a convenience method for making code modifications of ranges e.g. as identified by ``ASTTokens.get_text_range(node)``. Replacements is an iterable of ``(start, end, new_text)`` tuples. For example, ``replace("this is a test", [(0, 4, "X"), (8, 9, "THE")])`` produces ``"X is THE test"``. rN)sortedrjoin)rK replacementsppartsr=endnew_texts r"replacerFs! % &| 4 4  uc8 LLag LL AA,,tABBx r!ceZdZdZdZdZdS) NodeMethodsz[ Helper to get `visit_{node_type}` methods given a node's class and cache the results. ci|_dSr0)_cacher2s r"__init__zNodeMethods.__init__^s DKKKr!c|j|}|sz!combine_tokens..s,@@3sx8..@@@@@@r!ch|] }|j Sr )liners r"rdz!combine_tokens..sHcHcHcVYHcHcHcr!rrc3$K|] }|jV dSr0)r+)rats r"rz!combine_tokens..s$//Aqx//////r!rr)r1r+r=rr) rrrF TokenInforrr=rr)rs r"rrs @@%@@@ @ @CHcHc]bHcHcHcDdDdhiDiDi l ]ww///////Ahn "IM 1X]  r!cxdt||D}|rt|dS|S)zq If the given AST node contains multiple statements, return the last one. Otherwise, just return the node. c\g|])}t|st|jdv'|*S)) excepthandler ExceptHandler match_case MatchCase TryExcept TryFinally)r}r1r)rarns r" zlast_stmt..sQ   u~~ e-2 r!r)rS last_stmt)rR child_stmtss r"rrsT  /)$//55   +& [_ % %% +r!)maxsizecdtj}dtj|D}d|D}tt |t|k}t fd|D}|o|S)a The positions attached to nodes inside f-string FormattedValues have some bugs that were fixed in Python 3.9.7 in https://github.com/python/cpython/pull/27729. This checks for those bugs more concretely without relying on the Python version. Specifically this checks: - Values with a format spec or conversion - Repeated (i.e. identical-looking) expressions - f-strings implicitly concatenated over multiple lines. - Multiline, triple-quoted f-strings. z( f"a {b}{b} c {d!r} e {f:g} h {i:{j}} k {l:{m:n}}" f"a {b}{b} c {d!r} e {f:g} h {i:{j}} k {l:{m:n}}" f"{x + y + z} {x} {y} {z} {z} {z!a} {z:z}" f''' {s} {t} {u} {v} ''' )cFg|]}t|tj|Sr )rXrZNamerarRs r"rz*fstring_positions_work..s)NNN:dCH3M3MNNNNr!c*g|]}|j|jfSr )r col_offsetrs r"rz*fstring_positions_work..s!JJJtT[$/2JJJr!c3TK|]"}tj||jkV#dSr0)rZget_source_segmentid)rarRsources r"rz)fstring_positions_work..sK   64((DG3      r!)rZparserrrall)tree name_nodesname_positionspositions_are_uniquecorrect_source_segmentsrs @r"fstring_positions_workrs & 6  $NN$NNN*JJzJJJ.S0011S5H5HH         9"99r!ctjdkrdSt|dD]}t|tjs|jD]}t|ddt|tjrSts(t|j D]}t|dd|j rt|j dddS)zy Add a special attribute `_broken_positions` to nodes inside f-strings if the lineno/col_offset cannot be trusted. ) NT)rV_broken_positions) sys version_inforrXrZrrhsetattrFormattedValuerrm format_spec)r joinedstrpartrns r"annotate_fstring_nodesrs     F666??i i / / ? ? d'... D#, - -?%'' 6DJ'' 6 6e E. 5 5 5 5   ? $"$7 > > > ???r!r0)F)IrZ collectionsrHrr&rFabcrrrr functoolsrtypingrr r r r r rrrrrrastroid_compatrrAstNoderr, namedtupler.r9r>rDrGrSrO__dict__itemsrkrPr|rxryr}rrUrConstantr__annotations__ astroid.nodesrr ImportErrorrrrrrobjectrrrrrrrrrrr r!r"rs  !!!!!!!!!!                            !$$$$$$C +v% &' )HHH..... "K "7,^ _ _...&QQQQ + + + +AAAWWWWWWccCL..00ccc ,HH#,"4"4"6"6HHHHH3<#5#5#7#7HHHOOOP 555 555 --- 000+++'*l_%c "444!!!!!!uh$,,, 666 ...    FHH ( ( ( V:(,2   . 4:::>?????s? E EE