o
    o^|                     @   s4  d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlmZ ddl	m
Z edZejejejejejejejejejejejejejejejejejejej ej!ej"ej#ej$ej%ej&ej'ej(ej)fZ*G d	d
 d
ej+Z,e, Z-dd Z.dd Z/dd Z0G dd dej1Z2dd Z3dd Z4dd Z5dd Z6dS )z%Helpers for working with python ASTs.    )absolute_import)division)print_functionN)errors)
formattingz+^[ 	]*#.*?coding[:=][ 	]*([-_.a-zA-Z0-9]+)c                       s    e Zd ZdZ fddZ  ZS )_TreeNormalizerz,Replaces all op nodes with unique instances.c                    s"   t |tr	| S tt| |S N)
isinstance_AST_OP_NODES	__class__superr   visitselfnoder    4lib/python3.10/site-packages/pasta/base/ast_utils.pyr   *   s   
z_TreeNormalizer.visit)__name__
__module____qualname____doc__r   __classcell__r   r   r   r   r   '   s    r   c                 C   s   t t| }t| |S )zReplaces ast.parse; ensures additional properties on the parsed tree.

  This enforces the assumption that each node in the ast is unique.
  )astparsesanitize_source_tree_normalizerr   )srcZtreer   r   r   r   3   s   
r   c                 C   sJ   |  d}t|dd D ]\}}t|rtdd|||< qd|S )zStrip the 'coding' directive from python source code, if present.

  This is a workaround for https://bugs.python.org/issue18960. Also see PEP-0263.
  TN   z#.*$z# (removed coding) )
splitlines	enumerate_CODING_PATTERNmatchresubjoin)r   Z	src_linesiliner   r   r   r   =   s   


r   c                    s    t  fdd}||  |jS )Nc                    s
   t |  S r   )r	   )naccept_typesr   r   <lambda>J   s   
 z$find_nodes_by_type.<locals>.<lambda>)FindNodeVisitorr   results)r   r+   Zvisitorr   r*   r   find_nodes_by_typeI   s   
r/   c                       s$   e Zd Zdd Z fddZ  ZS )r-   c                 C   s   || _ g | _d S r   )
_conditionr.   )r   Z	conditionr   r   r   __init__Q   s   
zFindNodeVisitor.__init__c                    s*   |  |r| j| tt| | d S r   )r0   r.   appendr   r-   r   r   r   r   r   r   U   s   
zFindNodeVisitor.visit)r   r   r   r1   r   r   r   r   r   r   r-   O   s    r-   c                 C   s~  t | tjrz| jd W S  ty   Y dS w t | tjrFt| jdkr=t | jd tjr=t	| jd dr=t
| jd S | jrE| jd S ntt | tjrmt| jdkrlt | jd tjrlt	| jd drlt
| jd S nMttdrt | tjr| jr| jd S | jr| jd S n1ttdrt | tjr| jr| jd S nttd	rt | tjr| jr| jd S | jrt
| jd S | jd S )
aR  Get the last child node of a block statement.

  The input must be a block statement (e.g. ast.For, ast.With, etc).

  Examples:
    1. with first():
         second()
         last()

    2. try:
         first()
       except:
         second()
       finally:
         last()

  In both cases, the last child is the node for `last`.
  N   r   Zis_elifZis_continuedTry
TryFinally	TryExcept)r	   r   ZModulebody
IndexErrorZIflenorelsefmtgetget_last_childZWithhasattrr5   	finalbodyr6   r7   handlersr   r   r   r   r>   [   sH    
 




r>   c                 C   sH   t | D ]\}}t|tr||v r||  d S qtd|| f )Nz9Unable to find list containing child %r on parent node %r)r   Ziter_fieldsr	   listremover   InvalidAstError)parentchild_Zfield_valuer   r   r   remove_child   s   
rI   c              	   C   s   t |tjrt|dt|d t|dt|d | jD ]/}t| |d}||kr4t| ||  dS t|t	rNz|||
|< W  dS  tyM   Y qw qtd|| f )zReplace a node's child with another node while preserving formatting.

  Arguments:
    parent: (ast.AST) Parent node to replace a child of.
    node: (ast.AST) Child node to replace.
    replace_with: (ast.AST) New child node.
  prefixsuffixNzNode %r is not a child of %r)r?   r<   Z
PASTA_DICTsetr=   _fieldsgetattrsetattrr	   rC   index
ValueErrorr   rE   )rF   r   Zreplace_withZfieldZ	field_valr   r   r   replace_child   s"   	

rR   c                 C   s6   t | do| jot| jd tjot| jd jtjS )Nr8   r   )r?   r8   r	   r   ZExprvalueZStrrB   r   r   r   has_docstring   s
   rT   )7r   Z
__future__r   r   r   r   r$   Zpasta.augmentr   Z
pasta.baser   r<   compiler"   ZAndZOrZEqZNotEqZIsZIsNotZInZNotInZLtZLtEZGtZGtEZAddZSubZMultZDivZModZPowZLShiftZRShiftZBitAndZBitOrZBitXorZFloorDivZInvertZNotZUAddZUSubr
   ZNodeTransformerr   r   r   r   r/   ZNodeVisitorr-   r>   rI   rR   rT   r   r   r   r   <module>   s0   
  	
2	