o w[e@sdZddlZddlTddlmZmZddlmZmZd`ddd d d Z d d Z daddddZ ddZ ddZ dbddZddZddZdcddZdd Zd!d"Zdd#d$d%Zd&d'ZGd(d)d)eZGd*d+d+eZeed,sd-d.Zd/d0Zeeee_eeee_Gd1d2d2e Z!d3d4Z"Gd5d6d6ee!d7Z#Gd8d9d9ee!d7Z$Gd:d;d;ee!d7Z%Gdd?d?ee!d7Z'e#e(e)e*fe$e+fe%e,fe&e de-fe'e d@fiZ.e#e-fiZ/e-d=e dd=e(d6e)d6e*d6e+d9e,d;e d@d?iZ0GdAdBdBe1Z2GdCdDdDe2Z3GdEdFdFe2Z4ee5dGs"dHdIZ6dJdKZ7ee6e7e5_8GdLdMdMe9Z:GdNdOdOe;ZdTe?ej@jAdZBGdUdVdVeZCdWZDdXZEgeDeERZFGdYdZdZeZGd[d\ZHd]d^ZIeJd_kryeIdSdS)daH ast ~~~ The `ast` module helps Python applications to process trees of the Python abstract syntax grammar. The abstract syntax itself might change with each Python release; this module helps to find out programmatically what the current grammar looks like and allows modifications of it. An abstract syntax tree can be generated by passing `ast.PyCF_ONLY_AST` as a flag to the `compile()` builtin function or by using the `parse()` function from this module. The result will be a tree of objects whose classes all inherit from `ast.AST`. A modified abstract syntax tree can be compiled into a Python code object using the built-in `compile()` function. Additionally various helper functions are provided that make working with the trees simpler. The main intention of the helper functions and this module in general is to provide an easy to use interface for libraries that work tightly with the python syntax (template engines for example). :copyright: Copyright 2008 by Armin Ronacher. :license: Python License. N)*)contextmanager nullcontext)IntEnumauto execF) type_commentsfeature_versioncCsRt}|r|tO}t|tr|\}}|dksJ|}n|dur d}t|||||dS)z Parse the source into an AST node. Equivalent to compile(source, filename, mode, PyCF_ONLY_AST). Pass type_comments=True to get back type comments where the syntax allows. N)_feature_version) PyCF_ONLY_ASTPyCF_TYPE_COMMENTS isinstancetuplecompile)sourcefilenamemoder r flagsmajorminorr/usr/lib/python3.10/ast.pyparse!s   rcsft|trt|ddd}t|tr|j}ddfddfdd fd d |S) aT Evaluate an expression node or a string containing only a Python expression. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and None. Caution: A complex expression can overflow the C stack and cause a crash. z evalrcSs4d}t|dd}r|d|7}t|d|)Nzmalformed node or stringlinenoz on line : )getattr ValueError)nodemsglnorrr_raise_malformed_nodeCsz+literal_eval.._raise_malformed_nodecs,t|trt|jtttfvr||jSN)rConstanttypevalueintfloatcomplexr")r%rr _convert_numHsz"literal_eval.._convert_numcsDt|trt|jttfr|j}t|jtr| S| S|Sr&)rUnaryOpopUAddUSuboperand)r"r3)r.rr_convert_signed_numLs   z)literal_eval.._convert_signed_numcsLt|tr|jSt|trtt|jSt|tr"tt|jSt|t r/t t|jSt|t rOt|j t rO|j jdkrO|j|jkrNgkrOt St|trqt|jt|jkrb|ttt|jt|jSt|trt|jttfr|j}|j}t|ttfrt|trt|jtr||S||S|S)Nset) rr'r)TuplermapeltsListlistSetr5CallfuncNameidargskeywordsDictlenkeysvaluesdictzipBinOpr0AddSubleftrightr*r+r,)r"rKrL_convertr.r4r%rrrNTs4    "     zliteral_eval.._convert)rstrrlstrip Expressionbody)node_or_stringrrMr literal_eval6s    rTT)indentcsTdfdd t|tstd|jjdur$tts$d|dS)a Return a formatted dump of the tree in node. This is mainly useful for debugging purposes. If annotate_fields is true (by default), the returned string will show the names and the values for fields. If annotate_fields is false, the result string will be more compact by omitting unambiguous field names. Attributes such as line numbers and column offsets are not dumped by default. If this is wanted, include_attributes can be set to true. If indent is a non-negative integer or string, then the tree will be pretty-printed with that indent level. None (the default) selects the single line representation. rc sdurd7d}d}nd}d}t|trt|}g}d}}|jD]@}zt||} Wn ty?d}Yq+w| durOt||ddurOd}q+| \} } |oY| }|rf|d|| fq+|| q+r|jr|jD]4}zt||} Wn tyYqtw| durt||ddurqt| \} } |o| }|d|| fqt|rt|d krd |j j d |f| fSd |j j || |fd fSt|t r|sd Sd|| fdd|Dfd fSt |dfS)N z, , T.z%s=%sr z%s(%s)z%s(%s%s)F)z[]Tz[%s%s]c3s|] }|dVqdSrNr).0x)_formatlevelrr sz(dump.._format..)rASTr(_fieldsr AttributeErrorappend _attributesrC __class____name__joinr:repr) r"r^prefixsepclsr@ allsimplerAnamer)simpler]annotate_fieldsinclude_attributesrU)r^rr]}s\         & zdump.._formatzexpected AST, got %rN )r)rr` TypeErrorrerfrO)r"rprqrUrrordumpqs  0 rtcCsVdD]&}||jvr(||jvr(t||d}|dus"t||r(|dr(t|||q|S)z Copy source location (`lineno`, `col_offset`, `end_lineno`, and `end_col_offset` attributes) from *old_node* to *new_node* if possible, and return *new_node*. )r col_offset end_linenoend_col_offsetNend_)rdr hasattr startswithsetattr)new_nodeold_nodeattrr)rrr copy_locations  rcs fdd|dddd|S)a{ When you compile a node tree with compile(), the compiler expects lineno and col_offset attributes for every node that supports them. This is rather tedious to fill in for generated nodes, so this helper adds these attributes recursively where not already set, by setting them to the values of the parent node. It works recursively starting at *node*. csd|jvrt|ds||_n|j}d|jvr%t|dddur"||_n|j}d|jvr6t|ds3||_n|j}d|jvrJt|dddurG||_n|j}t|D] }|||||qNdS)Nrrvrurw)rdryrr rvrurwiter_child_nodes)r"rrurvrwchild_fixrrrs&       z#fix_missing_locations.._fixrVrrr-rrrfix_missing_locationss rrVcCstt|D]3}t|trt|dd||_qd|jvr#t|dd||_d|jvr7t|dd}dur7|||_q|S)z Increment the line number and end line number of each node in the tree starting at *node* by *n*. This is useful to "move code" to a different location in a file. rrrvN)walkr TypeIgnorer rrdrv)r"nrrvrrrincrement_linenos     rc cs8|jD]}z |t||fVWqtyYqwdS)zs Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields`` that is present on *node*. N)rar rb)r"fieldrrr iter_fieldss  rccsNt|D]\}}t|tr|Vqt|tr$|D] }t|tr#|VqqdS)z Yield all direct child nodes of *node*, that is, all fields that are nodes and all items of fields that are lists of nodes. N)rrr`r:)r"rmritemrrrr s   rcCst|ttttfstd|jj|jrt|jdt sdS|jdj }t|t r-|j }nt|t r||||S|rOt||d|}nd}||||d} ||d|} ||d|}| d| | | d |S)aBGet source code segment of the *source* that generated *node*. If some location information (`lineno`, `end_lineno`, `col_offset`, or `end_col_offset`) is missing, return None. If *padded* is `True`, the first line of a multi-line statement will be padded with spaces to match its original position. NrVrXr) rvrwrrurbrencodedecoderinsertrcrg) rr"rrrvrurwrpaddingfirstlastrrrget_source_segmentWs,        rccsDddlm}||g}|r |}|t||V|sdSdS)z Recursively yield all descendant nodes in the tree starting at *node* (including *node* itself), in no specified order. This is useful if you only want to modify nodes in place and don't care about the context. r)dequeN) collectionsrpopleftextendr)r"rtodorrrr|s   rc@s(eZdZdZddZddZddZdS) NodeVisitora< A node visitor base class that walks the abstract syntax tree and calls a visitor function for every node found. This function may return a value which is forwarded by the `visit` method. This class is meant to be subclassed, with the subclass adding visitor methods. Per default the visitor functions for the nodes are ``'visit_'`` + class name of the node. So a `TryFinally` node visit function would be `visit_TryFinally`. This behavior can be changed by overriding the `visit` method. If no visitor function exists for a node (return value `None`) the `generic_visit` visitor is used instead. Don't use the `NodeVisitor` if you want to apply changes to nodes during traversing. For this a special visitor exists (`NodeTransformer`) that allows modifications. cCs"d|jj}t|||j}||S)z Visit a node.visit_)rerfr generic_visit)selfr"methodvisitorrrrvisits zNodeVisitor.visitcCsTt|D]#\}}t|tr|D] }t|tr||qqt|tr'||qdS)z9Called if no explicit visitor function exists for a node.N)rrr:r`r)rr"rr)rrrrrs     zNodeVisitor.generic_visitc Cs|j}tt|}|dur tD] \}}t||r|}nq|durKd|}zt||}Wn ty8Ynwddl}| |dt d||S| |S)Nrrz" is deprecated; add visit_Constant) r)_const_node_type_namesgetr(itemsrr rbwarningswarnDeprecationWarningr) rr"r) type_namerkrmrrrrrrvisit_Constants*    zNodeVisitor.visit_ConstantN)rf __module__ __qualname____doc__rrrrrrrrs  rc@eZdZdZddZdS)NodeTransformeraC A :class:`NodeVisitor` subclass that walks the abstract syntax tree and allows modification of nodes. The `NodeTransformer` will walk the AST and use the return value of the visitor methods to replace or remove the old node. If the return value of the visitor method is ``None``, the node will be removed from its location, otherwise it is replaced with the return value. The return value may be the original node in which case no replacement takes place. Here is an example transformer that rewrites all occurrences of name lookups (``foo``) to ``data['foo']``:: class RewriteName(NodeTransformer): def visit_Name(self, node): return Subscript( value=Name(id='data', ctx=Load()), slice=Constant(value=node.id), ctx=node.ctx ) Keep in mind that if the node you're operating on has child nodes you must either transform the child nodes yourself or call the :meth:`generic_visit` method for the node first. For nodes that were part of a collection of statements (that applies to all statement nodes), the visitor may also return a list of nodes rather than just a single node. Usually you use the transformer like this:: node = YourTransformer().visit(node) cCst|D]P\}}t|tr:g}|D]!}t|tr-||}|dur"qt|ts-||q||q||dd<qt|trT||}|durNt||qt|||q|Sr&) rrr:r`rrrcdelattrr{)rr"r old_value new_valuesr)r|rrrrs(          zNodeTransformer.generic_visitN)rfrrrrrrrrrs #rrcC|jS)zDeprecated. Use value instead.r)rrrr_getterrcC ||_dSr&rrr)rrr_setter rc@seZdZddZddZdS)_ABCcGs d|_dS)Nz3Deprecated AST node class. Use ast.Constant instead)r)rkr@rrr__init__rz _ABC.__init__cCsdt|tsdS|tvr,z|j}Wn tyYdSwt|t|o+t|t|d St||S)NFr) rr' _const_typesr)rb_const_types_notrr(__instancecheck__)rkinstr)rrrrs    z_ABC.__instancecheck__N)rfrrrrrrrrrs rcOsp|D]}||jvr q|j|}|t|kr t|jd|q|tvr,t|i|Stj|g|Ri|S)Nz" got multiple values for argument )raindexrCrsrfrr'__new__)rkr@kwargskeyposrrr_new"s   rc@eZdZdZeZdS)Num)rNrfrrrarrrrrrr.r) metaclassc@r)rrNrrrrrr2rrc@r)BytesrNrrrrrr6rrc@seZdZeZdS) NameConstantN)rfrrrrrrrrr:rc@r)EllipsisrcOs6|turtdg|Ri|Stj|g|Ri|S)N.)rr'r)rkr@rrrrr@szEllipsis.__new__N)rfrrrarrrrrr=s r.c@eZdZdZdS)slicezDeprecated AST node class.Nrfrrrrrrrr[rrc@r)Indexz@Deprecated AST node class. Use the index value directly instead.cKs|Sr&r)rkr)rrrrr`sz Index.__new__Nrfrrrrrrrrr^s rc@seZdZdZdddZdS)ExtSlicez1Deprecated AST node class. Use ast.Tuple instead.rcKstt|tfi|Sr&)r6r:Load)rkdimsrrrrreszExtSlice.__new__N)rrrrrrrcsrrcCr)zDeprecated. Use elts instead.r8rrrr _dims_gettermrrcCrr&rrrrr _dims_setterqrrc@r)Suite/Deprecated AST node class. Unused in Python 3.Nrrrrrrvrrc@r)AugLoadrNrrrrrryrrc@r)AugStorerNrrrrrr|rrc@r)ParamrNrrrrrrrr1ec@seZdZdZeZeZeZeZeZ eZ eZ eZ e Z eZeZeZeZeZeZeZeZeZddZdS) _Precedencez5Precedence table that originated from python grammar.cCs(z||dWSty|YSwNrV)rer!rrrrnexts  z_Precedence.nextN)rfrrrrTUPLEYIELDTESTORANDNOTCMPEXPRBORBXORBANDSHIFTARITHTERMFACTORPOWERAWAITATOMrrrrrrs* r)'")z"""z'''cseZdZdZddddZddZdd Zd d Zdd dZddZ ddZ e ddZ e ddddZe ddZddZddZdd Zd!d"Zd#d$Zd%d&Zfd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3d4Zd5d6Zd7d8Zd9d:Zd;d<Z d=d>Z!d?d@Z"dAdBZ#dCdDZ$dEdFZ%dGdHZ&dIdJZ'dKdLZ(dMdNZ)dOdPZ*dQdRZ+dSdTZ,dUdVZ-dWdXZ.dYdZZ/d[d\Z0d]d^Z1d_d`Z2dadbZ3dcddZ4dedfZ5dgdhZ6didjZ7dkdlZ8dmdnZ9dodpZ:e;ddqdrdsZdydzZ?d{d|Z@d}d~ZAddZBddZCddZDddZEddZFddZGddZHddZIddZJddZKddZLddZMddZNddZOddZPdddddZQeRjSeRjTeRjTeRjTdZUddZVdddddddddddddd ZWeRjXeRjXeRjYeRjYeRjYeRjYeRjZeRjZeRj[eRj\eRj]eRjYeRj^d Z_e`dZaddZbddddddddddd ZcddZddddĜZeeRjfeRjgdŜZhddDŽZiddɄZjdd˄Zkdd̈́ZlddτZmddфZnddӄZoddՄZpddׄZqddلZrddۄZsdd݄Ztdd߄ZuddZvddZwddZxddZyddZzddZ{ddZ|ddZ}ddZ~ddZZS) _UnparserzMethods in this class recursively traverse an AST and output source code for the abstract syntax; original formatting is disregarded.F_avoid_backslashescCs(g|_g|_i|_i|_d|_||_dS)Nr)_source_buffer _precedences _type_ignores_indentr)rrrrrrs  z_Unparser.__init__cCsJt|}z|t|Wn tyYdSw|D] }|||qdS)z7Call f on each item in seq, calling inter() in between.N)iterr StopIteration)rinterfseqr\rrr interleaves  z_Unparser.interleavecs@t|dkr||dddSfdd||dS)zTraverse and separate the given *items* with a comma and append it to the buffer. If *items* is a single item sequence, a trailing comma will be added.rVr,c dSNrYwriterrrr z&_Unparser.items_view..N)rCrr)r traverserrrrr items_views  z_Unparser.items_viewcCs|jr |ddSdS)z8Adds a newline if it isn't the start of generated sourcerWN)rrrrrr maybe_newlinesz_Unparser.maybe_newlinerXcCs ||d|j|dS)zXIndent a piece of text and append it, according to the current indentation levelz N)r#rrrrrrrfillsz_Unparser.fillcCs|j|dS)zAppend a piece of textN)rrcr$rrrrsz_Unparser.writecCs|j|dSr&)rrcr$rrr buffer_writerz_Unparser.buffer_writercCsd|j}|j|S)NrX)rgrclearrrrrbuffers  z_Unparser.bufferNextraccs@|d|r |||jd7_dV|jd8_dS)aA context manager for preparing the source for blocks. It adds the character':', increases the indentation on enter and decreases the indentation on exit. If *extra* is given, it will be directly appended after the colon character. :rVN)rr)rr+rrrblocks  z_Unparser.blockccs ||dV||dS)zA context manager for preparing the source for expressions. It adds *start* to the buffer and enters, after exit it adds *end*.Nr)rstartendrrrdelimits z_Unparser.delimitcCs|r|||StSr&)r0r)rr.r/ conditionrrr delimit_ifs z_Unparser.delimit_ifcCs|dd|||kS)z,Shortcut to adding precedence related parens())r2get_precedence)r precedencer"rrrrequire_parenssz_Unparser.require_parenscCs|j|tjSr&)rrrrrr"rrrr5r'z_Unparser.get_precedencecGs|D]}||j|<qdSr&)r)rr6nodesr"rrrset_precedences z_Unparser.set_precedencecCsdt|ttttfrt|jdkrdS|jd}t|tsdS|j}t|t r.t|jt r0|SdSdS)zIf a docstring node is found in the body of the *node* parameter, return that docstring node, None otherwise. Logic mirrored from ``_PyAST_GetDocString``.rVNr) rrrrrrCrRrr)r'rOr8rrrget_raw_docstring s   z_Unparser.get_raw_docstringcCs*|j|jp |j}|durd|SdS)Nz # type: )rrr type_comment)rr"commentrrrget_type_comments z_Unparser.get_type_commentcs2t|tr|D]}||qdSt|dSr&)rr:traversesuperr)rr"rrerrr?!s  z_Unparser.traversecCsg|_||d|jS)zOutputs a source code string that, if converted back to an ast (using ast.parse) will generate an AST equivalent to *node*rX)rr?rgr8rrrr+s  z_Unparser.visitcCs@||}r||||jdddS||jdSr)r;_write_docstringr?rR)rr" docstringrrr"_write_docstring_and_traverse_body2s z,_Unparser._write_docstring_and_traverse_bodycCs*dd|jD|_|||jdS)NcSsi|] }|jd|jqS)ignore)rtag)r[rErrr :sz*_Unparser.visit_Module..) type_ignoresrrDr(r8rrr visit_Module9s  z_Unparser.visit_Modulecs`ddfddj|jWdn1swYd|jdS)Nr3r4crrrrrrrrDr z._Unparser.visit_FunctionType.. -> )r0rr?argtypesrreturnsr8rrrvisit_FunctionTypeAs z_Unparser.visit_FunctionTypecCs(||tj|j||jdSr&)r%r:rrr)r?r8rrr visit_ExprJsz_Unparser.visit_ExprcCsj|tj|$|tj|j|j||j|d||jWddS1s.wYdS)Nz := ) r7rrr:r targetr)r?rr8rrrvisit_NamedExprOs   "z_Unparser.visit_NamedExprc(dfddj|jdS)Nzimport crrrrrrrrXr z(_Unparser.visit_Import..)r%rr?namesr8rrr visit_ImportV z_Unparser.visit_ImportcsXdd|jp d|jr|jdfddj|jdS)Nzfrom .rz import crrrrrrrr`r z,_Unparser.visit_ImportFrom..)r%rr^modulerr?rRr8rrrvisit_ImportFromZs   z_Unparser.visit_ImportFromcCsT||jD] }|||dq||j||}r(||dSdS)N = )r%targetsr?rr)r>)rr"rOr<rrr visit_Assignbs    z_Unparser.visit_AssigncCsB|||j|d|j|jjjd||jdS)Nrrz= ) r%r?rOrbinopr0rerfr)r8rrrvisit_AugAssignks z_Unparser.visit_AugAssigncCs||dd|j ot|jt||jWdn1s$wY|d||j|j rD|d||j dSdS)Nr3r4rrX) r%r2rnrrOr>r?r annotationr)r8rrrvisit_AnnAssignqs    z_Unparser.visit_AnnAssigncCs.|d|jr|d||jdSdS)Nreturnrr)r%r)rr?r8rrr visit_Return{s  z_Unparser.visit_ReturncC|ddS)Npassr%r8rrr visit_Passz_Unparser.visit_PasscCra)Nbreakrcr8rrr visit_Breakrez_Unparser.visit_BreakcCra)Ncontinuercr8rrrvisit_Continuerez_Unparser.visit_ContinuecrQ)Nzdel crrrrrrrrr z(_Unparser.visit_Delete..)r%rr?rYr8rrr visit_DeleterTz_Unparser.visit_DeletecCs:|d||j|jr|d||jdSdS)Nzassert rY)r%r?testr#rr8rrr visit_Asserts   z_Unparser.visit_AssertcrQ)Nzglobal crrrrrrrrr z(_Unparser.visit_Global..r%rrrRr8rrr visit_GlobalrTz_Unparser.visit_GlobalcrQ)Nz nonlocal crrrrrrrrr z*_Unparser.visit_Nonlocal..rmr8rrrvisit_NonlocalrTz_Unparser.visit_NonlocalcCz|tj|,|d|jr+|d|tj|j||jWddSWddS1s6wYdS)Nawaitrr)r7rrrr)r:r r?r8rrr visit_Await  "z_Unparser.visit_AwaitcCrp)Nyieldrr)r7rrrr)r:r r?r8rrr visit_Yieldrsz_Unparser.visit_YieldcCsh|tj|#|d|jstd|tj|j||jWddS1s-wYdS)Nz yield from z-Node can't be used without a value attribute.) r7rrrr)r!r:r r?r8rrrvisit_YieldFroms "z_Unparser.visit_YieldFromcCs\|d|js|jrtddS|d||j|jr,|d||jdSdS)Nraisez*Node can't use cause without an exception.rrz from )r%exccauser!rr?r8rrr visit_Raises    z_Unparser.visit_RaisecCs|d|||jWdn1swY|jD]}||q"|jrL|d|||jWdn1sGwY|jrq|d|||jWddS1sjwYdSdS)Ntryelsefinally)r%r-r?rRhandlersorelse finalbody)rr"exrrr visit_Trys"        "z_Unparser.visit_TrycCs||d|jr|d||j|jr!|d||j|||jWddS1s7wYdS)Nexceptrr as )r%r(rr?rmr-rRr8rrrvisit_ExceptHandlers      "z_Unparser.visit_ExceptHandlercCs||jD] }|d||q|d|j|jdd|jp%|jd4d}|jD]}|r8|dnd}||q.|jD]}|rM|dnd}||qCWdn1s_wY| | |WddS1sywYdS) N@zclass r3r4)r1FrYT) r#decorator_listr%r?rmr2basesrArr-rD)rr"decocommaerrrvisit_ClassDefs,           "z_Unparser.visit_ClassDefcC||ddS)Ndef_function_helperr8rrrvisit_FunctionDefr'z_Unparser.visit_FunctionDefcCr)Nz async defrr8rrrvisit_AsyncFunctionDefr'z _Unparser.visit_AsyncFunctionDefcCs||jD] }|d||q|d|j}|||dd||jWdn1s7wY|jrJ|d||j|j | |d| |WddS1sdwYdS)Nrrrr3r4rJr*) r#rr%r?rmr0r@rLrr-r>rD)rr" fill_suffixrdef_strrrrrs       "z_Unparser._function_helpercC|d|dS)Nzfor  _for_helperr8rrr visit_Forr'z_Unparser.visit_ForcCr)Nz async for rr8rrrvisit_AsyncFor r'z_Unparser.visit_AsyncForcCs||||j|d||j|j||d||jWdn1s0wY|jrZ|d|||jWddS1sSwYdSdS)N in r*r|) r%r?rOrrr-r>rRr)rr%r"rrrrs      "z_Unparser._for_helpercCs4|d||j|||jWdn1s wY|jrst|jdkrst|jdtrs|jd}|d||j|||jWdn1s\wY|jrst|jdkrst|jdts7|jr|d|||jWddS1swYdSdS)Nzif rVrzelif r|) r%r?rkr-rRrrCrIfr8rrrvisit_Ifs&   $    $  "z_Unparser.visit_IfcCs|d||j|||jWdn1s wY|jrJ|d|||jWddS1sCwYdSdS)Nzwhile r|)r%r?rkr-rRrr8rrr visit_While,s     "z_Unparser.visit_Whilechdfddj|jj|d|jWddS1s-wYdS)Nzwith crrrrrrrr8r z&_Unparser.visit_With..r*r%rr?rr-r>rRr8rrr visit_With6 "z_Unparser.visit_Withcr)Nz async with crrrrrrrr>r z+_Unparser.visit_AsyncWith..r*rr8rrrvisit_AsyncWith<rz_Unparser.visit_AsyncWith quote_typesescape_special_whitespacecsfdd}dt||}dvrdd|D}fdd|D}|sAttfdd |Dd }d d |gfSrm|jfd dd|d d d krmt|d dksaJdd dd |fS)zHelper for writing string literals, minimizing escapes. Returns the tuple (string literal to write, possible quote types). cs4s|dvr|S|dks|s|ddS|S)Nz \unicode_escapeascii) isprintablerr)r)rrr escape_charHs z2_Unparser._str_literal_helper..escape_charrXrWcSsg|]}|tvr|qSr) _MULTI_QUOTESr[qrrr Uz1_Unparser._str_literal_helper..csg|]}|vr|qSrrrescaped_stringrrrVrc3s |] }d|vr|VqdSrZrr)stringrrr_\sz0_Unparser._str_literal_helper..rrVr cs|ddkS)Nrr r)rrrrr`sz/_Unparser._str_literal_helper..)rr Nr)rgr7rhrsortrC)rrrrrpossible_quotesquoter)rrrr_str_literal_helperBs  z_Unparser._str_literal_helperrcCs4|j||d\}}|d}||||dS)zKWrite string literal value with a best effort attempt to avoid backslashes.rrN)rr)rrr quote_typerrr_write_str_avoiding_backslasheshsz)_Unparser._write_str_avoiding_backslashesc Cs|d|jr|||j||jdSg}|jD]}t|dt|j }|||j| |jt |t fqg}t }|D]\}}|j|||d\}}| |q@d|}|d}||||dS)Nr _fstring_rrXr)rr_fstring_JoinedStrr&rr)rEr r(rfrcrr' _ALL_QUOTESrrg) rr"r)r)meth new_bufferr is_constantrrrrvisit_JoinedStrns*       z_Unparser.visit_JoinedStrcCs(|d|||j||jdS)Nr)r_fstring_FormattedValuer&rr)r8rrrvisit_FormattedValues z_Unparser.visit_FormattedValuecCs.|jD]}t|dt|j}|||qdS)Nr)rEr r(rf)rr"rr)rrrrrs  z_Unparser._fstring_JoinedStrcCs6t|jts td|jdddd}||dS)Nz.Constants inside JoinedStr should be a string.{z{{}z}})rr)rOr!replace)rr"rr)rrr_fstring_Constants  z_Unparser._fstring_ConstantcCs|dt|dd}|tj|j||j}|dr$|dd|vr,td|||j dkrIt |j }|dvrBtd |d ||j ra|d t |d t|j j }||j ||d dS)NrTr rrrz5Unable to avoid backslash in f-string expression partr srazUnknown f-string conversion.!r,rr)r(r:rrrr)rrzr! conversionchr format_specr rf)rr"runparserexprrrrrrrs&      z!_Unparser._fstring_FormattedValuecC||jdSr&)rr?r8rrr visit_Namer'z_Unparser.visit_NamecCs0||jdkr|d|j|jtddS)Nur)r%kindrrr)rr8rrrrBs  z_Unparser._write_docstringc Csnt|ttfr|t|dtddtdtddS|jr.t|tr.| |dS|t|dS)Ninfnanr3-r4) rr+r,rrhr_INFSTRrrOrrrrr_write_constantsz_Unparser._write_constantcCs|j}t|tr(|dd||j|WddS1s!wYdS|dur3|ddS|jdkr=|d||jdS)Nr3r4....r)r)rrr0r"rrr)rr"r)rrrrs "  z_Unparser.visit_ConstantcLddfddj|jWddS1swYdS)N[]crrrrrrrrr z&_Unparser.visit_List..)r0rr?r8r8rrr visit_Lists"z_Unparser.visit_ListcCT|dd||j|jD]}||qWddS1s#wYdS)Nrrr0r?elt generatorsrr"genrrrvisit_ListComp    "z_Unparser.visit_ListCompcCrNr3r4rrrrrvisit_GeneratorExprz_Unparser.visit_GeneratorExpcCr)Nrrrrrrr visit_SetComprz_Unparser.visit_SetCompcCsj|dd%||j|d||j|jD]}||qWddS1s.wYdS)Nrrr)r0r?rrr)rrrrrvisit_DictComps     "z_Unparser.visit_DictCompcCs|jr |dn|d|tj|j||j|d|jtj|j g|j R||j |j D] }|d||q9dS)Nz async for z for r if ) is_asyncrr:rrrOr?rrrifs)rr" if_clauserrrvisit_comprehensions        z_Unparser.visit_comprehensioncCs|tj|9|tj|j|j||j|d||j|d|tj|j ||j WddS1sCwYdS)Nrz else ) r7rrr:rrRrkr?rrr8rrr visit_IfExps    "z_Unparser.visit_IfExpcs`|jr)ddfddj|jWddS1s"wYdSddS)Nrrcrrrrrrrrr z%_Unparser.visit_Set..z{*()})r8r0rr?rr8rrr visit_Set s "z_Unparser.visit_Setcslfddfdd}ddfdd|t|j|jWddS1s/wYdS) Ncs"|d|dSNrr?r)kvrrrwrite_key_value_pairs  z2_Unparser.visit_Dict..write_key_value_paircsD|\}}|durdtj||dS||dS)N**)rr:rrr?)rrrrrrr write_items  z(_Unparser.visit_Dict..write_itemrrcrrrrrrrr'r z&_Unparser.visit_Dict..)r0rrGrDrE)rr"rrrr visit_Dicts  "z_Unparser.visit_DictcCsB|dd||j|jWddS1swYdSr)r0r"r?r8r8rrr visit_Tuple*s"z_Unparser.visit_Tuple~not+r)InvertNotr1r2)rrrrcCs|j|jjj}|j|}|||%|||tjur#|d| ||j | |j WddS1s;wYdSNrr) unopr0rerfunop_precedencer7rrrr:r3r?)rr"operatoroperator_precedencerrr visit_UnaryOp6s    "z_Unparser.visit_UnaryOprr/%<<>>|^&//r) rIrJMultMatMultDivModLShiftRShiftBitOrBitXorBitAndFloorDivPow) rrrrrrrrrr r r r)rcCs|j|jjj}|j|}|||>||jvr |}|}n|}|}|||j | |j | d|d|||j | |j WddS1sTwYdSr) r[r0rerfbinop_precedencer7 binop_rassocrr:rKr?rrL)rr"rrleft_precedenceright_precedencerrr visit_BinOpcs   "z_Unparser.visit_BinOpz==z!=z>=iszis notinznot in) EqNotEqLtLtEGtGtEIsIsNotInNotIncCs|tj|=|jtj|jg|jR||jt|j |jD]\}}| d|j |j j d||q$WddS1sGwYdSr)r7rrr:rrK comparatorsr?rGopsrcmpopsrerf)rr"orrrr visit_Compares  "z_Unparser.visit_Compareandor)AndOr)r/r0csj|jjj}j|fdd}|d|dfdd||jWddS1s9wYdS)Ncs"||dSr&)rr:r?r-)rrrrincreasing_level_traverses z9_Unparser.visit_BoolOp..increasing_level_traverserrcs Sr&rr)rrrrrr z(_Unparser.visit_BoolOp..)boolopsr0rerfboolop_precedencer7rrE)rr"rr3r)rrrr visit_BoolOps  "z_Unparser.visit_BoolOpcCsZ|tj|j||jt|jtr t|jjtr |d|d||j dS)NrrrU) r:rr r)r?rr'r*rr~r8rrrvisit_Attributes    z_Unparser.visit_AttributecCs|tj|j||j|dd5d}|jD]}|r$|dnd}||q|jD]}|r9|dnd}||q/WddS1sLwYdS)Nr3r4FrYT) r:rr r=r?r0r@rrA)rr"rrrrr visit_Calls        "z_Unparser.visit_CallcCsdd}|tj|j||j|dd&||jr(||j|jjn||jWddSWddS1sAwYdS)NcSs&t|to|jotdd|jD S)Ncss|]}t|tVqdSr&)rStarred)r[rrrrr_szE_Unparser.visit_Subscript..is_simple_tuple..)rr6r8any) slice_valuerrris_simple_tuples z2_Unparser.visit_Subscript..is_simple_tuplerr) r:rr r)r?r0rr"r8)rr"r<rrrvisit_Subscripts  "z_Unparser.visit_SubscriptcCs*|d|tj|j||jdS)Nr)rr:rrr)r?r8rrr visit_Starreds z_Unparser.visit_StarredcCra)Nrrr8rrrvisit_Ellipsisrez_Unparser.visit_EllipsiscCsR|jr ||j|d|jr||j|jr'|d||jdSdS)Nr,)lowerr?rupperstepr8rrr visit_Slices    z_Unparser.visit_SlicecCsZ|d||j||jD]}||qWddS1s&wYdS)Nzmatch )r%r?subjectr-cases)rr"caserrr visit_Matchs     "z_Unparser.visit_MatchcCs0||j|jr|d||jdSdSr)rargr]r?r8rrr visit_arg  z_Unparser.visit_argc Csd}|j|j}dgt|t|j|j}tt||dD]/\}}|\}}|r,d}n|d|||rB|d|||t|jkrN|dq|jsU|j r~|rZd}n|d|d|jr~||jj |jj r~|d||jj |j rt|j |j D]\}}|d|||r|d||q|j r|rd}n|d|d |j j |j j r|d||j j dSdSdS) NTrVFrY=z, /rrr) posonlyargsr@rCdefaults enumeraterGrr?vararg kwonlyargsrHr] kw_defaultskwarg) rr"rall_argsrMrelementsadrrrvisit_argumentssV                z_Unparser.visit_argumentscCs<|jdur |dn ||j|d||jdS)NrrK)rHrr?r)r8rrr visit_keywords    z_Unparser.visit_keywordcCsp|tj|'|d||j|d|tj|j||jWddS1s1wYdS)Nzlambda r)r7rrrr?r@r:rRr8rrr visit_Lambda$s   "z_Unparser.visit_LambdacCs*||j|jr|d|jdSdSNr)rrmasnamer8rrr visit_alias,s z_Unparser.visit_aliascCs0||j|jr|d||jdSdSrZ)r? context_expr optional_varsrr8rrrvisit_withitem1rJz_Unparser.visit_withitemcCsl|d||j|jr|d||j|||jWddS1s/wYdS)Nzcase r)r%r?patternguardrr-rRr8rrrvisit_match_case7s     "z_Unparser.visit_match_casecCrr&)r?r)r8rrrvisit_MatchValue@r'z_Unparser.visit_MatchValuecCrr&)rr)r8rrrvisit_MatchSingletonCr'z_Unparser.visit_MatchSingletoncr)NrrcrrrrrrrrIr z/_Unparser.visit_MatchSequence..)r0rr?patternsr8rrrvisit_MatchSequenceFs "z_Unparser.visit_MatchSequencecCs&|j}|dur d}|d|dS)N_r)rmr)rr"rmrrrvisit_MatchStarLsz_Unparser.visit_MatchStarc sfdd}dd;|j}fdd|t||jdd|j}|dur?|r/d d |WddSWddS1sJwYdS) Ncs*|\}}|d|dSrr)pairrprrrwrite_key_pattern_pairSs  z<_Unparser.visit_MatchMapping..write_key_pattern_pairrrcrrrrrrrr\r z._Unparser.visit_MatchMapping..TstrictrYr)r0rDrrGrerestr)rr"rkrDrnrrrvisit_MatchMappingRs   "z_Unparser.visit_MatchMappingc stj|j|jddC|j}fddj||j}|rOfdd}|r6 dfdd|t ||j d d WddSWddS1sZwYdS) Nr3r4crrrrrrrrlr z,_Unparser.visit_MatchClass..cs&|\}}|d|dS)NrK)rr?)rir~r`rrrwrite_attr_patternpsz6_Unparser.visit_MatchClass..write_attr_patternrYcrrrrrrrrxr Trl) r:rr rkr?r0rer kwd_attrsrrG kwd_patterns)rr"reattrsrprrrvisit_MatchClassfs(    "z_Unparser.visit_MatchClasscCs|j}|j}|dur|ddS|dur||jdS|tj| |tj|j||j|d|jWddS1sGwYdS)Nrgr) rmr`rr7rrr:rr?)rr"rmr`rrr visit_MatchAs}s "z_Unparser.visit_MatchAscshtj|#jtjg|jRfddj|jWddS1s-wYdS)Ncr)Nz | rrrrrrr z)_Unparser.visit_MatchOr..)r7rrr:rrerr?r8rrr visit_MatchOrs"z_Unparser.visit_MatchOr)rX)rfrrrrrr"r#r%rr&propertyr)rr-r0r2r7r5r:r;r>r?rrDrIrMrNrPrSrWrZr\r^r`rdrgrirjrlrnrorrrurvrzrrrrrrrrrrrrrrrrrrrrrrrBrrrrrrrrrrrrrrrrrrr[rrrrrrrr frozensetrrr,r.r4rrr5r6r7r8r=r>r?rCrGrIrWrXrYr\r_rbrcrdrfrhrortrurv __classcell__rrrArr s4              &       3  r cCst}||Sr&)r r)ast_objrrrrunparses r{cCsddl}|jdd}|jd|jddddd d |jd d d ddd|jddddd|jddddd|jddtddd|}|j }|}Wdn1sTwYt||jj |j |j d }t t ||j|jd!dS)"Nrz python -m ast)proginfilerbr?rz$the file to parse; defaults to stdin)r(nargsdefaulthelpz-mz--moder)rsingler func_typez(specify what kind of code must be parsed)rchoicesrz--no-type-commentsT store_falsez)don't add information about type comments)ractionrz-az--include-attributes store_truez:include attributes such as line numbers and column offsets)rrz-iz--indentr z'indentation of nodes (number of spaces))r(rr)r )rqrU)argparseArgumentParser add_argumentFileTyper* parse_argsr}readrrmrno_type_commentsprintrtrqrU)rparserr@r}rtreerrrmains2      r__main__)rr)TF)rV)T)Krsys_ast contextlibrrenumrrrrTrtrrrrrrrrrrobjectrrryr'rrrwrrr(rrrrrrrr*r+r,rObytesboolrrrr`rrrr6rrrmodr expr_contextrrrrh float_info max_10_exprr_SINGLE_QUOTESrrr r{rrfrrrrs ;C #  %: <         m