o
    o^                     @   sx   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
 ddl	mZ d	d
 Zdd Zdd ZdS )z Rename names in a python module.    )absolute_import)division)print_functionN)import_utils)	ast_utils)scopec                 C   sT  t | }||jvrdS d}i }g }|j| D ]}t|jtjrh||j}t|tjrO||vrOt	||||s9J |
ddd ||
ddd < || n||jjt|d  |j_|jjse|||< d}qt|jtjr|j|vrt	||j||s~J |
ddd ||
ddd < ||j d}qt|D ]\}	}
t|| |	|
 q|S )a  Rename an imported name in a module.

  This will rewrite all import statements in `tree` that reference the old
  module as well as any names in `tree` which reference the imported name. This
  may introduce new import statements, but only if necessary.

  For example, to move and rename the module `foo.bar.utils` to `foo.bar_utils`:
  > rename_external(tree, 'foo.bar.utils', 'foo.bar_utils')

  - import foo.bar.utils
  + import foo.bar_utils

  - from foo.bar import utils
  + from foo import bar_utils

  - from foo.bar import logic, utils
  + from foo.bar import logic
  + from foo import bar_utils

  Arguments:
    t: (ast.Module) Module syntax tree to perform the rename in. This will be
      updated as a result of this function call with all affected nodes changed
      and potentially new Import/ImportFrom nodes added.
    old_name: (string) Fully-qualified path of the name to replace.
    new_name: (string) Fully-qualified path of the name to update to.

  Returns:
    True if any changes were made, False otherwise.
  F.   NT)r   ZanalyzeZexternal_references
isinstancenodeastaliasparentZ
ImportFrom_rename_name_in_importfromrsplitappendnamelenasnamesixZ	iteritems_rename_reads)told_namenew_nameschas_changedrenamesZalready_changedrefr   Z
rename_oldZ
rename_new r   4lib/python3.10/site-packages/pasta/augment/rename.pyrename_external   s6   

 
 r!   c           	      C   s   ||krdS |j d}|d}|d}|d t| |kr0d||t|d   |_ dS |jD ]}|j|d kr> nq3dS |d |_||d d krrt|jdkrht| ||}d|d d |_ dS d|d d |_ dS )NFr   Tr
   r	   )modulesplitr   joinnamesr   r   Zsplit_import)	r   r   r   r   Zmodule_partsZ	old_partsZ	new_partsZalias_to_changeZ
new_importr   r   r    r   ^   s*   



r   c           	      C   s   | d}z| j|d  }|dd D ]}|j| }qW n
 ty&   Y dS w d}|jD ]}t|tjtjfrJt	
| ||t|jd j d}q,|S )ap  Updates all locations in the module where the given name is read.

  Arguments:
    sc: (scope.Scope) Scope to work in. This should be the scope of `t`.
    t: (ast.AST) The AST to perform updates in.
    old_name: (string) Dotted name to update.
    new_name: (string) Dotted name to replace it with.

  Returns:
    True if any changes were made, False otherwise.
  r   r   r	   NFT)r#   r%   ZattrsKeyErrorZreadsr   r   NameZ	Attributer   Zreplace_childr   parsebodyvalue)	r   r   r   r   Z
name_partsr   partr   Zref_noder   r   r    r      s$   

r   )__doc__Z
__future__r   r   r   r   r   Zpasta.augmentr   Z
pasta.baser   r   r!   r   r   r   r   r   r    <module>   s   A!