o ?Og@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)Z PyCF_ONLY_ASTZPyCF_TYPE_COMMENTS isinstancetuplecompile)sourcefilenamemoder r flagsmajorminorr*/opt/alt/python310/lib64/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$)rZUnaryOpopUAddUSuboperand)r r0)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'TuplermapeltsZListlistSetr2ZCallfuncNameidargskeywordsZDictlenkeysvaluesdictzipZBinOpr-AddSubleftrightr(r)r*)r rDrE_convertr,r1r#rrrGTs4    "     zliteral_eval.._convert)rstrrlstripZ Expressionbody)Znode_or_stringrrFr literal_eval6s    rKT)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&_fieldsrAttributeErrorappend _attributesr= __class____name__joinr6repr) r rUprefixsepclsr;Z allsimpler<namer'simplerTannotate_fieldsinclude_attributesrL)rUrrT}s\         & zdump.._formatzexpected AST, got %rN )r)rrW TypeErrorr\r]rH)r rfrgrLrrerdumpqs  0 rjcCsVdD]&}||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_offsetNZend_)r[rhasattr startswithsetattr)new_nodeZold_nodeattrr'rrr copy_locations  rscs 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)Nrrlrkrm)r[rnrrrlrkrmiter_child_nodes)r rrkrlrmchild_fixrrrws&       z#fix_missing_locations.._fixrMrrr+rrvrfix_missing_locationss rxrMcCstt|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. rrrlN)walkrZ TypeIgnorerrr[rl)r nrurlrrrincrement_linenos     r{c cs8|jD]}z |t||fVWqtyYqwdS)zs Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields`` that is present on *node*. N)rXrrY)r fieldrrr iter_fieldss  r}ccsNt|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)r}rrWr6)r rcr|itemrrrrt s   rtcCst|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. NrMrOr) rlrmrrkrYrencodedecoderinsertrZr^) rr rrrlrkrmrZpaddingfirstZlastrrrget_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) collectionsrpopleftextendrt)r rZtodorrrry|s   ryc@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_)r\r]r 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)r}rr6rWr)rr r|r'r~rrrrs     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&itemsrrrYwarningswarnDeprecationWarningr) rr r'Z type_namerbrcrrrrrrvisit_Constants*    zNodeVisitor.visit_ConstantN)r] __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$) r}rr6rWrrrZdelattrrp)rr r| old_valueZ new_valuesr'rqrrrrs(          zNodeTransformer.generic_visitN)r]rrrrrrrrrs #rrzcC|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)rbr;rrr__init__rz _ABC.__init__cCsdt|tsdS|tvr,z|j}Wn tyYdSwt|t|o+t|t|d St||S)NFr) rr% _const_typesr'rY_const_types_notrr&__instancecheck__)rbinstr'rrrrs    z_ABC.__instancecheck__N)r]rrrrrrrrrs rcOsp|D]}||jvr q|j|}|t|kr t|jd|q|tvr,t|i|Stj|g|Ri|S)Nz" got multiple values for argument )rXindexr=rir]rr%__new__)rbr;kwargskeyposrrr_new"s   rc@eZdZdZeZdS)Num)rzNr]rrrXrrrrrrr.r) metaclassc@r)rrNrrrrrr2rrc@r)BytesrNrrrrrr6rrc@seZdZeZdS) NameConstantN)r]rrrrrrrrr:rc@r)EllipsisrcOs6|turtdg|Ri|Stj|g|Ri|S)N.)rr%r)rbr;rrrrr@szEllipsis.__new__N)r]rrrXrrrrrr=s r.c@eZdZdZdS)slicezDeprecated AST node class.Nr]rrrrrrrr[rrc@r)Indexz@Deprecated AST node class. Use the index value directly instead.cKs|Sr$r)rbr'rrrrr`sz Index.__new__Nr]rrrrrrrrr^s rc@seZdZdZdddZdS)ExtSlicez1Deprecated AST node class. Use ast.Tuple instead.rcKstt|tfi|Sr$)r3r6ZLoad)rbdimsrrrrreszExtSlice.__new__N)rrrrrrrcsrrcCr)zDeprecated. Use elts instead.r5rrrr _dims_gettermrrcCrr$rrrrr _dims_setterqrrc@r)Suite/Deprecated AST node class. Unused in Python 3.Nrrrrrrvrrc@r)AugLoadrNrrrrrryrrc@r)AugStorerNrrrrrr|rrc@r)ParamrNrrrrrrrrZ1ec@seZdZdZeZeZeZeZeZ eZ eZ eZ e Z eZeZeZeZeZeZeZeZeZddZdS) _Precedencez5Precedence table that originated from python grammar.cCs(z||dWSty|YSwNrM)r\rrrrrnexts  z_Precedence.nextN)r]rrrrTUPLEYIELDTESTORANDNOTCMPEXPRBORBXORBANDSHIFTARITHTERMFACTORPOWERAWAITATOMrrrrrrs* 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)rZinterfseqrSrrr 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.rMr,c dSNrPwriterrrr z&_Unparser.items_view..N)r=rr)rZ traverserrrrr items_views  z_Unparser.items_viewcCs|jr |ddSdS)z8Adds a newline if it isn't the start of generated sourcerNN)rrrrrr maybe_newlinesz_Unparser.maybe_newlinerOcCs ||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)rrZr rrrrsz_Unparser.writecCs|j|dSr$)rrZr rrr buffer_writerz_Unparser.buffer_writercCsd|j}|j|S)NrO)r^rclearrrrrbuffers  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. :rMN)rr)rrrrrblocks  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$)rr)rrr conditionrrr delimit_ifs z_Unparser.delimit_ifcCs|dd|||kS)z,Shortcut to adding precedence related parens())rget_precedence)r precedencer rrrrequire_parenssz_Unparser.require_parenscCs|j|tjSr$)rrrrrr rrrrrz_Unparser.get_precedencecGs|D]}||j|<qdSr$)r)rrZnodesr 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``.rMNr) rrrrrr=rJrr'r%rHrrrrget_raw_docstring s   z_Unparser.get_raw_docstringcCs*|j|jp |j}|durd|SdS)Nz # type: )rrr type_comment)rr Zcommentrrrget_type_comments z_Unparser.get_type_commentcs2t|tr|D]}||qdSt|dSr$)rr6traversesuperr)rr r~r\rrr$!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*rO)rr$r^rrrrr+s  z_Unparser.visitcCs@||}r||||jdddS||jdSr)r!_write_docstringr$rJ)rr Z docstringrrr"_write_docstring_and_traverse_body2s z,_Unparser._write_docstring_and_traverse_bodycCs*dd|jD|_|||jdS)NcSsi|] }|jd|jqS)ignore)rtag)rRr)rrr :sz*_Unparser.visit_Module..) type_ignoresrr(rrrrr visit_Module9s  z_Unparser.visit_Modulecs`ddfddj|jWdn1swYd|jdS)NrrcrrrrrrrrDrz._Unparser.visit_FunctionType.. -> )rrr$argtypesrreturnsrrrrvisit_FunctionTypeAs z_Unparser.visit_FunctionTypecCs(||tj|j||jdSr$)r r rrr'r$rrrr visit_ExprJsz_Unparser.visit_ExprcCsj|tj|$|tj|j|j||j|d||jWddS1s.wYdS)Nz := ) rrrr rtargetr'r$rrrrrvisit_NamedExprOs   "z_Unparser.visit_NamedExprc(dfddj|jdS)Nzimport crrrrrrrrXrz(_Unparser.visit_Import..)r rr$namesrrrr visit_ImportV z_Unparser.visit_ImportcsXdd|jp d|jr|jdfddj|jdS)Nzfrom .rz import crrrrrrrr`rz,_Unparser.visit_ImportFrom..)r rrUmodulerr$r6rrrrvisit_ImportFromZs   z_Unparser.visit_ImportFromcCsT||jD] }|||dq||j||}r(||dSdS)N = )r targetsr$rr'r#)rr r3r"rrr visit_Assignbs    z_Unparser.visit_AssigncCsB|||j|d|j|jjjd||jdS)Nrhz= ) r r$r3rbinopr-r\r]r'rrrrvisit_AugAssignks z_Unparser.visit_AugAssigncCs||dd|j ot|jt||jWdn1s$wY|d||j|j rD|d||j dSdS)Nrrrr<) r rrdrr3r9r$r annotationr'rrrrvisit_AnnAssignqs    z_Unparser.visit_AnnAssigncCs.|d|jr|d||jdSdS)Nreturnrh)r r'rr$rrrr visit_Return{s  z_Unparser.visit_ReturncC|ddS)Npassr rrrr visit_Passz_Unparser.visit_PasscCrE)NbreakrGrrrr visit_BreakrIz_Unparser.visit_BreakcCrE)NcontinuerGrrrrvisit_ContinuerIz_Unparser.visit_Continuecr5)Nzdel crrrrrrrrrz(_Unparser.visit_Delete..)r rr$r=rrrr visit_Deleter8z_Unparser.visit_DeletecCs:|d||j|jr|d||jdSdS)Nzassert rP)r r$testr!rrrrr visit_Asserts   z_Unparser.visit_Assertcr5)Nzglobal crrrrrrrrrz(_Unparser.visit_Global..r rrr6rrrr visit_Globalr8z_Unparser.visit_Globalcr5)Nz nonlocal crrrrrrrrrz*_Unparser.visit_Nonlocal..rQrrrrvisit_Nonlocalr8z_Unparser.visit_NonlocalcCz|tj|,|d|jr+|d|tj|j||jWddSWddS1s6wYdS)Nawaitrh)rrrrr'r rr$rrrr visit_Await  "z_Unparser.visit_AwaitcCrT)Nyieldrh)rrrrr'r rr$rrrr visit_YieldrWz_Unparser.visit_YieldcCsh|tj|#|d|jstd|tj|j||jWddS1s-wYdS)Nz yield from z-Node can't be used without a value attribute.) rrrrr'rr rr$rrrrvisit_YieldFroms "z_Unparser.visit_YieldFromcCs\|d|js|jrtddS|d||j|jr,|d||jdSdS)Nraisez*Node can't use cause without an exception.rhz from )r exccauserrr$rrrr visit_Raises    z_Unparser.visit_RaisecCs|d|||jWdn1swY|jD]}||q"|jrL|d|||jWdn1sGwY|jrq|d|||jWddS1sjwYdSdS)Ntryelsefinally)r rr$rJhandlersorelse finalbody)rr Zexrrr visit_Trys"        "z_Unparser.visit_TrycCs||d|jr|d||j|jr!|d||j|||jWddS1s7wYdS)Nexceptrh as )r r&rr$rcrrJrrrrvisit_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 rr)rFrPT) r decorator_listr r$rcrbasesr<rrr()rr decocommaerrrvisit_ClassDefs,           "z_Unparser.visit_ClassDefcC||ddS)Ndef_function_helperrrrrvisit_FunctionDefrz_Unparser.visit_FunctionDefcCrp)Nz async defrrrrrrvisit_AsyncFunctionDefrz _Unparser.visit_AsyncFunctionDefcCs||jD] }|d||q|d|j}|||dd||jWdn1s7wY|jrJ|d||j|j | |d| |WddS1sdwYdS)Nrirhrrr.r) r rjr r$rcrr;r0rrr#r()rr Z fill_suffixrlZdef_strrrrrss       "z_Unparser._function_helpercC|d|dS)Nzfor  _for_helperrrrr visit_Forrz_Unparser.visit_ForcCrv)Nz async for rwrrrrvisit_AsyncFor rz_Unparser.visit_AsyncForcCs||||j|d||j|j||d||jWdn1s0wY|jrZ|d|||jWddS1sSwYdSdS)N in rr`) r r$r3rrrr#rJrc)rr r rrrrxs      "z_Unparser._for_helpercCs4|d||j|||jWdn1s wY|jrst|jdkrst|jdtrs|jd}|d||j|||jWdn1s\wY|jrst|jdkrst|jdts7|jr|d|||jWddS1swYdSdS)Nzif rMrzelif r`) r r$rOrrJrcr=rZIfrrrrvisit_Ifs&   $    $  "z_Unparser.visit_IfcCs|d||j|||jWdn1s wY|jrJ|d|||jWddS1sCwYdSdS)Nzwhile r`)r r$rOrrJrcrrrr visit_While,s     "z_Unparser.visit_Whilechdfddj|jj|d|jWddS1s-wYdS)Nzwith crrrrrrrr8rz&_Unparser.visit_With..rr rr$rrr#rJrrrr visit_With6 "z_Unparser.visit_Withcr~)Nz async with crrrrrrrr>rz+_Unparser.visit_AsyncWith..rrrrrrvisit_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 \Zunicode_escapeascii) isprintablerr)r)rrr escape_charHs z2_Unparser._str_literal_helper..escape_charrOrNcSsg|]}|tvr|qSr) _MULTI_QUOTESrRqrrr Uz1_Unparser._str_literal_helper..csg|]}|vr|qSrrrescaped_stringrrrVrc3s |] }d|vr|VqdSrQrr)stringrrrV\sz0_Unparser._str_literal_helper..rrMr cs|ddkS)Nrr r)rrrrr`sz/_Unparser._str_literal_helper..)rr Nr)r^r4r_rsortr=)rrrrrZpossible_quotesZquoter)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_rrOr)rr_fstring_JoinedStrr rrr?rr&r]rZrr% _ALL_QUOTESrr^) rr rr'methZ new_bufferrZ is_constantrrrrvisit_JoinedStrns*       z_Unparser.visit_JoinedStrcCs(|d|||j||jdS)Nr)r_fstring_FormattedValuer rrrrrrvisit_FormattedValues z_Unparser.visit_FormattedValuecCs.|jD]}t|dt|j}|||qdS)Nr)r?rr&r])rr rr'rrrrrs  z_Unparser._fstring_JoinedStrcCs6t|jts td|jdddd}||dS)Nz.Constants inside JoinedStr should be a string.{z{{}z}})rr'rHrreplace)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)NrTrrhrz5Unable to avoid backslash in f-string expression partr ZsrazUnknown f-string conversion.!rrr)r&r rrrr'rror conversionchr format_specrr])rr runparserexprrrrrrrs&      z!_Unparser._fstring_FormattedValuecC||jdSr$)rr:rrrr visit_Namerz_Unparser.visit_NamecCs0||jdkr|d|j|jtddS)Nur)r kindrrr'rrrrrr's  z_Unparser._write_docstringc Csnt|ttfr|t|dtddtdtddS|jr.t|tr.| |dS|t|dS)Ninfnanr-r) rr)r*rr_r_INFSTRrrHrrrrr_write_constantsz_Unparser._write_constantcCs|j}t|tr(|dd||j|WddS1s!wYdS|dur3|ddS|jdkr=|d||jdS)Nrr....r)r'rrrr rrr)rr r'rrrrs "  z_Unparser.visit_ConstantcLddfddj|jWddS1swYdS)N[]crrrrrrrrrz&_Unparser.visit_List..)rrr$r5rrrr visit_Lists"z_Unparser.visit_ListcCT|dd||j|jD]}||qWddS1s#wYdS)Nrrrr$elt generatorsrr genrrrvisit_ListComp    "z_Unparser.visit_ListCompcCrNrrrrrrrvisit_GeneratorExprz_Unparser.visit_GeneratorExpcCr)Nrrrrrrr visit_SetComprz_Unparser.visit_SetCompcCsj|dd%||j|d||j|jD]}||qWddS1s.wYdS)Nrrr)rr$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 rrr3r$rrrifs)rr Z if_clauserrrvisit_comprehensions        z_Unparser.visit_comprehensioncCs|tj|9|tj|j|j||j|d||j|d|tj|j ||j WddS1sCwYdS)Nrz else ) rrrr rrJrOr$rrcrrrr visit_IfExps    "z_Unparser.visit_IfExpcs`|jr)ddfddj|jWddS1s"wYdSddS)Nrrcrrrrrrrrrz%_Unparser.visit_Set..z{*()})r5rrr$rrrrr 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$)r~rrrrrr write_items  z(_Unparser.visit_Dict..write_itemrrcrrrrrrrr'rz&_Unparser.visit_Dict..)rrrAr>r?)rr rrrr visit_Dicts  "z_Unparser.visit_DictcCsB|dd||j|jWddS1swYdSr)rr r$r5rrrr visit_Tuple*s"z_Unparser.visit_Tuple~not+r)ZInvertZNotr.r/)rrrrcCs|j|jjj}|j|}|||%|||tjur#|d| ||j | |j WddS1s;wYdSNrh) unopr-r\r]unop_precedencerrrrr r0r$)rr operatoroperator_precedencerrr visit_UnaryOp6s    "z_Unparser.visit_UnaryOprri/%<<>>|^&//r) rBrCZMultZMatMultZDivZModZLShiftZRShiftZBitOrZBitXorZBitAndZFloorDivZPow) rrrrirrrrrrrrr)rcCs|j|jjj}|j|}|||>||jvr |}|}n|}|}|||j | |j | d|d|||j | |j WddS1sTwYdSr) r?r-r\r]binop_precedencer binop_rassocrr rDr$rrE)rr rrZleft_precedenceZright_precedencerrr visit_BinOpcs   "z_Unparser.visit_BinOpz==z!=z>=iszis notinznot in) ZEqZNotEqZLtZLtEZGtZGtEZIsZIsNotZInZNotIncCs|tj|=|jtj|jg|jR||jt|j |jD]\}}| d|j |j j d||q$WddS1sGwYdSr)rrrr rrD comparatorsr$rAopsrcmpopsr\r])rr ornrrr visit_Compares  "z_Unparser.visit_Compareandor)ZAndZOr)rrcsj|jjj}j|fdd}|d|dfdd||jWddS1s9wYdS)Ncs"||dSr$)rr r$r+)rrrrincreasing_level_traverses z9_Unparser.visit_BoolOp..increasing_level_traverserhcs Sr$rr)rrrrrrz(_Unparser.visit_BoolOp..)boolopsr-r\r]boolop_precedencerrr?)rr rrr)rrrr visit_BoolOps  "z_Unparser.visit_BoolOpcCsZ|tj|j||jt|jtr t|jjtr |d|d||j dS)Nrhr9) r rrr'r$rr%r(rrrrrrrvisit_Attributes    z_Unparser.visit_AttributecCs|tj|j||j|dd5d}|jD]}|r$|dnd}||q|jD]}|r9|dnd}||q/WddS1sLwYdS)NrrFrPT) r rrr8r$rr;rr<)rr rmrnrrr visit_Calls        "z_Unparser.visit_CallcCsdd}|tj|j||j|dd&||jr(||j|jjn||jWddSWddS1sAwYdS)NcSs&t|to|jotdd|jD S)Ncss|]}t|tVqdSr$)rZStarred)rRrrrrrVszE_Unparser.visit_Subscript..is_simple_tuple..)rr3r5any)Z slice_valuerrris_simple_tuples z2_Unparser.visit_Subscript..is_simple_tuplerr) r rrr'r$rrr r5)rr rrrrvisit_Subscripts  "z_Unparser.visit_SubscriptcCs*|d|tj|j||jdS)Nr)rr rrr'r$rrrr visit_Starreds z_Unparser.visit_StarredcCrE)Nrrrrrrvisit_EllipsisrIz_Unparser.visit_EllipsiscCsR|jr ||j|d|jr||j|jr'|d||jdSdS)Nr)lowerr$ruppersteprrrr visit_Slices    z_Unparser.visit_SlicecCsZ|d||j||jD]}||qWddS1s&wYdS)Nzmatch )r r$subjectrcases)rr caserrr visit_Matchs     "z_Unparser.visit_MatchcCs0||j|jr|d||jdSdSr)rargrAr$rrrr 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) NTrMFrP=z, /rrr) posonlyargsr;r=defaults enumeraterArr$vararg kwonlyargsrrA kw_defaultskwarg) rr rZall_argsr relementsadrrrvisit_argumentssV                z_Unparser.visit_argumentscCs<|jdur |dn ||j|d||jdS)Nrr)rrr$r'rrrr visit_keywords    z_Unparser.visit_keywordcCsp|tj|'|d||j|d|tj|j||jWddS1s1wYdS)Nzlambda r)rrrrr$r;r rJrrrr visit_Lambda$s   "z_Unparser.visit_LambdacCs*||j|jr|d|jdSdSNrg)rrcasnamerrrr visit_alias,s z_Unparser.visit_aliascCs0||j|jr|d||jdSdSr)r$ context_expr optional_varsrrrrrvisit_withitem1rz_Unparser.visit_withitemcCsl|d||j|jr|d||j|||jWddS1s/wYdS)Nzcase r)r r$patternguardrrrJrrrrvisit_match_case7s     "z_Unparser.visit_match_casecCrr$)r$r'rrrrvisit_MatchValue@rz_Unparser.visit_MatchValuecCrr$)rr'rrrrvisit_MatchSingletonCrz_Unparser.visit_MatchSingletoncr)NrrcrrrrrrrrIrz/_Unparser.visit_MatchSequence..)rrr$patternsrrrrvisit_MatchSequenceFs "z_Unparser.visit_MatchSequencecCs&|j}|dur d}|d|dS)N_r)rcr)rr rcrrrvisit_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\rz._Unparser.visit_MatchMapping..TstrictrPr)rr>rrAr restr)rr r&r>r)rrrvisit_MatchMappingRs   "z_Unparser.visit_MatchMappingc stj|j|jddC|j}fddj||j}|rOfdd}|r6 dfdd|t ||j d d WddSWddS1sZwYdS) Nrrcrrrrrrrrlrz,_Unparser.visit_MatchClass..cs&|\}}|d|dS)Nr)rr$)r$rrrrrrwrite_attr_patternpsz6_Unparser.visit_MatchClass..write_attr_patternrPcrrrrrrrrxrTr') r rrrbr$rr r kwd_attrsrrA kwd_patterns)rr r Zattrsr+rrrvisit_MatchClassfs(    "z_Unparser.visit_MatchClasscCs|j}|j}|dur|ddS|dur||jdS|tj| |tj|j||j|d|jWddS1sGwYdS)Nr"rg) rcrrrrrr rr$)rr rcrrrr visit_MatchAs}s "z_Unparser.visit_MatchAscshtj|#jtjg|jRfddj|jWddS1s-wYdS)Ncr)Nz | rrrrrrrz)_Unparser.visit_MatchOr..)rrrr rr rr$rrrr visit_MatchOrs"z_Unparser.visit_MatchOr)rO)r]rrrrrr r r rr propertyrrrrrrrr r!r#r$rr(r-r1r2r4r7r;r>r@rBrDrHrKrMrNrPrRrSrVrYrZr^rerhrortrursryrzrxr|r}rrrrrrrrrrrr'rrrrrrrrrrrrrrrrrrr?rrrrrrrr frozensetrrrrrrrrrrrrrrrrrrrrrrrrrr!r#r*r.r/r0 __classcell__rrr&rrs4              &       3  rcCst}||Sr$)rr)Zast_objrrrrunparses r4cCsddl}|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)rZsinglerZ func_typez(specify what kind of code must be parsed)r:choicesr;z--no-type-commentsTZ store_falsez)don't add information about type comments)r:actionr;z-az--include-attributes store_truez:include attributes such as line numbers and column offsets)r=r;z-iz--indentr z'indentation of nodes (number of spaces))r&r:r;)r )rgrL)argparseArgumentParser add_argumentZFileTyper( parse_argsr6readrrcrZno_type_commentsprintrjrgrL)r?parserr;r6rZtreerrrmains2      rF__main__)rr)TF)rM)T)KrsysZ_ast contextlibrrenumrrrrKrjrsrxr{r}rtrrrrryobjectrrrnr%rrr1rzrr&rrrrrrrr(r)r*rHbytesboolrrrrWrrrr3rrrmodrZ expr_contextrrrr_ float_info max_10_exprrZ_SINGLE_QUOTESrrrr4rFr]rrrrs ;C #  %: <         m