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_versioncCsFt}|r|tO}t|tr|\}}|}n|durd}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)r Constanttypevalueintfloatcomplexr)r"rr _convert_numHsz"literal_eval.._convert_numcsDt|trt|jttfr|j}t|jtr| S| S|Sr#)r ZUnaryOpopUAddUSuboperand)rr/)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) r r$r&TuplermapeltsZListlistSetr1ZCallfuncNameidargskeywordsZDictlenkeysvaluesdictzipZBinOpr,AddSubleftrightr'r(r))rrCrD_convertr+r0r"rrrFTs4    "     zliteral_eval.._convert)r strrlstripZ Expressionbody)Znode_or_stringrrEr literal_eval6s    rJT)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=%sz%s(%s)z%s(%s%s)F)z[]Tz[%s%s]c3s|] }|dVqdSrNr).0x)_formatlevelrr sz(dump.._format..)r ASTr%_fieldsrAttributeErrorappend _attributesr< __class____name__joinr5repr) rrUprefixsepclsr:Z allsimpler;namer&simplerTannotate_fieldsinclude_attributesrK)rUrrT}s\         & zdump.._formatzexpected AST, got %rN )r)r rW TypeErrorr\r]rG)rrfrgrKrrerdumpqs  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)rrrkrlrmchild_fixrrrws&       z#fix_missing_locations.._fixrLrrr*rrvrfix_missing_locationss rxrLcCstt|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)walkr Z TypeIgnorerrr[rl)rnrurlrrrincrement_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)rfieldrrr 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}r rWr5)rrcr|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. NrLrNr) rlrmrrkrYrencodedecoderinsertrZr^) rrrrrlrkrmrZpaddingfirstZlastrrrget_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)rrZtodorrrry|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)selfrmethodvisitorrrrvisits zNodeVisitor.visitcCsTt|D]#\}}t|tr|D] }t|tr||qqt|tr'||qdS)z9Called if no explicit visitor function exists for a node.N)r}r r5rWr)rrr|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%itemsr rrYwarningswarnDeprecationWarningr) rrr&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}r r5rWrrrZdelattrrp)rrr| 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) r r$ _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#)r2r5ZLoad)rbdimsrrrrreszExtSlice.__new__N)rrrrrrrcsrrcCr)zDeprecated. Use elts instead.r4rrrr _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|YSwNrL)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.rLr,c dSNrOwriterrrr 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 sourcerMN)rrrrrr maybe_newlinesz_Unparser.maybe_newlinerNcCs ||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)NrN)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. :rLN)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 precedencerrrrrequire_parenssz_Unparser.require_parenscCs|j|tjSr#)rrrrrrrrrrrz_Unparser.get_precedencecGs|D]}||j|<qdSr#)r)rrZnodesrrrrset_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``.rLNr) r rrrrr<rIrr&r$rGrrrrget_raw_docstring s   z_Unparser.get_raw_docstringcCs*|j|jp |j}|durd|SdS)Nz # type: )rrr type_comment)rrZcommentrrrget_type_comments z_Unparser.get_type_commentcs2t|tr|D]}||qdSt|dSr#)r r5traversesuperr)rrr~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*rN)rr$r^rrrrr+s  z_Unparser.visitcCs@||}r||||jdddS||jdSr)r!_write_docstringr$rI)rrZ 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#)rrr3r"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 rrdr r3r8r$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 rO)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$rIhandlersorelse finalbody)rrZexrrr visit_Trys"        "z_Unparser.visit_TrycCs||d|jr|d||j|jr!|d||j|||jWddS1s7wYdS)Nexceptrh as )r r%rr$rcrrIrrrrvisit_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)rFrOT) r decorator_listr r$rcrbasesr;rrr()rrdecocommaerrrvisit_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()rrZ 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#rIrc)rr rrrrrxs      "z_Unparser._for_helpercCs4|d||j|||jWdn1s wY|jrst|jdkrst|jdtrs|jd}|d||j|||jWdn1s\wY|jrst|jdkrst|jdts7|jr|d|||jWddS1swYdSdS)Nzif rLrzelif r`) r r$rOrrIrcr<r ZIfrrrrvisit_Ifs&   $    $  "z_Unparser.visit_IfcCs|d||j|||jWdn1s wY|jrJ|d|||jWddS1sCwYdSdS)Nzwhile r`)r r$rOrrIrcrrrr visit_While,s     "z_Unparser.visit_Whilechdfddj|jj|d|jWddS1s-wYdS)Nzwith crrrrrrrr8rz&_Unparser.visit_With..rr rr$rrr#rIrrrr 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 |gfSrc|jfd dd|d d d krcdd 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_charrNrMcSsg|]}|tvr|qSr) _MULTI_QUOTESrRqrrr Uz1_Unparser._str_literal_helper..csg|]}|vr|qSrrrescaped_stringrrrVrc3s |] }d|vr|VqdSrQrr)stringrrrV\sz0_Unparser._str_literal_helper..rrLr cs|ddkS)Nrr r)rrrrr`sz/_Unparser._str_literal_helper..)rNr)r^r3r_rsort)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_rrNr)rr_fstring_JoinedStrr rrr>rr%r]rZr r$ _ALL_QUOTESrr^) rrrr&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])rrrr&rrrrrs  z_Unparser._fstring_JoinedStrcCs6t|jts td|jdddd}||dS)Nz.Constants inside JoinedStr should be a string.{z{{}z}})r r&rGrreplace)rrrr&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])rrrunparserexprrrrrrrs&      z!_Unparser._fstring_FormattedValuecC||jdSr#)rr9rrrr 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) r r(r)rr_r_INFSTRrrGrrrrr_write_constantsz_Unparser._write_constantcCs|j}t|tr(|dd||j|WddS1s!wYdS|dur3|ddS|jdkr=|d||jdS)Nrr....r)r&r rrr rrr)rrr&rrrrs "  z_Unparser.visit_ConstantcLddfddj|jWddS1swYdS)N[]crrrrrrrrrz&_Unparser.visit_List..)rrr$r4rrrr visit_Lists"z_Unparser.visit_ListcCT|dd||j|jD]}||qWddS1s#wYdS)Nrrrr$elt generatorsrrgenrrrvisit_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)rrZ if_clauserrrvisit_comprehensions        z_Unparser.visit_comprehensioncCs|tj|9|tj|j|j||j|d||j|d|tj|j ||j WddS1sCwYdS)Nrz else ) rrrr rrIrOr$rrcrrrr visit_IfExps    "z_Unparser.visit_IfExpcs`|jr)ddfddj|jWddS1s"wYdSddS)Nrrcrrrrrrrrrz%_Unparser.visit_Set..z{*()})r4rrr$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..)rrr@r=r>)rrrrrr visit_Dicts  "z_Unparser.visit_DictcCsB|dd||j|jWddS1swYdSr)rr r$r4rrrr 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 r/r$)rroperatoroperator_precedencerrr visit_UnaryOp6s    "z_Unparser.visit_UnaryOprri/%<<>>|^&//r) rArBZMultZMatMultZDivZModZLShiftZRShiftZBitOrZBitXorZBitAndZFloorDivZPow) rrrrirrrrrrrrr)rcCs|j|jjj}|j|}|||>||jvr |}|}n|}|}|||j | |j | d|d|||j | |j WddS1sTwYdSr) r?r,r\r]binop_precedencer binop_rassocrr rCr$rrD)rrrrZleft_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 rrC comparatorsr$r@opsrcmpopsr\r])rrornrrr 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>)rrrrr)rrrr visit_BoolOps  "z_Unparser.visit_BoolOpcCsZ|tj|j||jt|jtr t|jjtr |d|d||j dS)Nrhr9) r rrr&r$r r$r'rrrrrrrvisit_Attributes    z_Unparser.visit_AttributecCs|tj|j||j|dd5d}|jD]}|r$|dnd}||q|jD]}|r9|dnd}||q/WddS1sLwYdS)NrrFrOT) r rrr7r$rr:rr;)rrrmrnrrr visit_Calls        "z_Unparser.visit_CallcCsdd}|tj|j||j|dd&||jr(||j|jjn||jWddSWddS1sAwYdS)NcSs&t|to|jotdd|jD S)Ncss|]}t|tVqdSr#)r ZStarred)rRrrrrrVszE_Unparser.visit_Subscript..is_simple_tuple..)r r2r4any)Z slice_valuerrris_simple_tuples z2_Unparser.visit_Subscript..is_simple_tuplerr) r rrr&r$rrr r4)rrrrrrvisit_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)rrcaserrr 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) NTrLFrO=z, /rrr) posonlyargsr:r<defaults enumerater@rr$vararg kwonlyargsrrA kw_defaultskwarg) rrrZall_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 rIrrrr 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$patternguardrrrIrrrrvisit_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)rrrcrrrvisit_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..TstrictrOr)rr=rr@r restr)rrr&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_patternrOcrrrrrrrrxrTr') r rrrbr$rr r kwd_attrsrr@ kwd_patterns)rrr Zattrsr+rrrvisit_MatchClassfs(    "z_Unparser.visit_MatchClasscCs|j}|j}|dur|ddS|dur||jdS|tj| |tj|j||j|d|jWddS1sGwYdS)Nr"rg) rcrrrrrr rr$)rrrcrrrr 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)rN)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--indentrPz'indentation of nodes (number of spaces))r%r:r;)r )rgrK)argparseArgumentParser add_argumentZFileTyper' parse_argsr6readrrcrZno_type_commentsprintrjrgrK)r?parserr:r6rZtreerrrmains2      rF__main__)rr)TF)rL)T)KrsysZ_ast contextlibrrenumrrrrJrjrsrxr{r}rtrrrrryobjectrrrnr$rrr1rzrr%rrrrrrrr'r(r)rGbytesboolrrrrWrrrr2rrrmodrZ expr_contextrrrr_ float_info max_10_exprrZ_SINGLE_QUOTESrrrr4rFr]rrrrs ;C #  %: <         m