a
    gT>                     @  s  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lm	Z	 d dlm
Z
 dZd	Zd
ZdZdZdZdZdZdZddddddddddZddddddddddZddddddddddZddddddddddZddddd d!d"Zddddd d#d$Zddd%d&d'd(Zdddd)d*d+d,Zd-d.d/d0Zeeee  ZZ ddd1d&d2d3Z!dddd&d4d5Z"G d6d7 d7Z#dddd&d8d9Z$dddd:d;d<d=Z%dddd:d>d?d@Z&ddddAd dBdCZ'dddd:d dDdEZ(dddFd:d dGdHZ)ddddd:dIdJdKZ*dddFdLd:dMdNdOZ+e,-dPdQdRZ.ddddSdTdUZ/dddVdLd:dWdXdYZ0dddVdLd:dZd[d\Z1dS )]    )annotationsN)defaultdict)NON_CODING_TOKENS)UNIMPORTANT_WS)Token)tokens_to_srcCODECOMMENTDEDENTINDENTNEWLINENAMEOPNLSTRINGsrclist[Token]intstrz
str | None)tokensinamer   returnc                C  s2   | | j |ks$|dur.| | j|kr.|d7 }q |S )z4
    Find the next token matching name and src.
    N   r   r   r   r   r   r    r   T/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/django_upgrade/tokens.pyfind   s    $
r   c                C  s2   | | j |ks$|dur.| | j|kr.|d8 }q |S )z8
    Find the previous token matching name and src.
    Nr   r   r   r   r   r   reverse_find#   s    $
r    c                C  s:   | |d  j |kr6|du s,| |d  j|kr6|d7 }q |S )z5
    Move past any tokens matching name and src.
    r   Nr   r   r   r   r   consume.   s    ,
r!   c                C  s:   | |d  j |kr6|du s,| |d  j|kr6|d8 }q |S )z7
    Rewind past any tokens matching name and src.
    r   Nr   r   r   r   r   reverse_consume7   s    ,
r"   z!ast.expr | ast.keyword | ast.stmt)r   r   noder   c                C  sT   | | j du s| | j |jk r(|d7 }q | | jdu sF| | j|jk rP|d7 }q(|S )zC
    Find the first token corresponding to the given ast node.
    Nr   )linelinenoutf8_byte_offset
col_offsetr   r   r#   r   r   r   find_first_tokenB   s    

r)   c                C  sX   | | j du s| | j |jk r(|d7 }q | | jdu sF| | j|jk rP|d7 }q(|d S )zB
    Find the last token corresponding to the given ast node.
    Nr   )r$   
end_linenor&   end_col_offsetr(   r   r   r   find_last_tokenR   s    

r,   ztuple[int, str])r   r   r   c                 C  s>   |dkr2| |d  j ttfv r2|d8 }| | j}nd}||fS )z
    If the previous token is an indent, return its position and the
    indentation string. Otherwise return the current position and "".
    r   r    )r   r   r   r   )r   r   indentr   r   r   extract_indentb   s
    r/   bool)r   	start_idxend_idxr   c                 C  s6   | |d  j tko4| |d  j tko4| |d  j tkS )zH
    Return if the given set of tokens is on its own physical line.
       r   )r   PHYSICAL_NEWLINEr   )r   r1   r2   r   r   r   alone_on_lineo   s
    r5   )]})([{z!tuple[list[tuple[int, int]], int]c                 C  s   g }|g}|d7 }|}|r| | }t |dkrP|jdkrP|||f |d }n\|jtv rf|| nF|jt| |d  j kr|  |st| ||  r|||f |d7 }q||fS )z
    Given the index of the opening bracket of a function call, step through
    and parse its arguments into a list of tuples of start, end indices.
    Return this list plus the position of the token after.
    r   ,)lenr   appendBRACESpopr   strip)r   r   argsstackZ	arg_starttokenr   r   r   parse_call_args   s"    	


rF   c                 C  sR   d}|s| | j dkrN| | j tv r.|d7 }n| | j tv rD|d8 }|d7 }q|S )Nr   :r   )r   OPENINGCLOSING)r   r   depthr   r   r   find_block_start   s    

rK   c                   @  s   e Zd ZdZdZdddddddddZd	dd
ddZd	dd
ddZd	dd
ddZd	d	ddddZ	d	d d
ddZ
edd	ddd dddZdS )Blockz
    Adapted from pyupgrade:
    https://github.com/asottile/pyupgrade/blob/ad5d9db9a206bfd221760fd81e407bf6040c808c/pyupgrade/_token_helpers.py#L179

    Copyright (c) 2017 Anthony Sottile

    MIT Licensed
    startcolonblockendr$   r   r0   None)rN   rO   rP   rQ   r$   r   c                 C  s"   || _ || _|| _|| _|| _d S NrM   )selfrN   rO   rP   rQ   r$   r   r   r   __init__   s
    zBlock.__init__r   )r   r   c                 C  s(   || j  j r t|| j  jS dS d S )Nr   )rN   r   isspacer>   )rT   r   r   r   r   _initial_indent   s    zBlock._initial_indentc                 C  s   d }t | j| jD ]`}||d  jdv r|| jdtfv r||d  jdkrt|| j}|d u rh|}qt||}q|d usJ |S )Nr   )r   r   r   r	   )rangerP   rQ   r   r   r>   r   min)rT   r   Zblock_indentr   Ztoken_indentr   r   r   _minimum_indent   s    zBlock._minimum_indentc                 C  s   | j r
d S | |}| || }t| j| jD ]b}||d  jdv r0|| jdtfv r0|| j}|d | ||| d   }|| j	|d||< q0d S )Nr   )r
   r   r   r   r   )
r$   rW   rZ   rX   rP   rQ   r   r   r   _replace)rT   r   initial_indentdiffr   sr   r   r   dedent   s    

zBlock.dedent)r   newr   c                 C  s0   | j }|| jdkr|d7 }q|||| j< d S )Nr   r   )rN   r   rO   )rT   r   r`   rN   r   r   r   replace_condition   s    
zBlock.replace_conditionc                 C  s   | j d  }}|| jtddhB v r|| jdv rd||d  jtkrdt||d  j| |krdqn|| jdv rv|}|d8 }q| j| j| j	| j
|d | jdS )z^the tokenizer reports the end of the block at the beginning of
        the next block
        r   r
   r   >   r   r   rM   )rQ   r   r   r   r>   r   rW   	__class__rN   rO   rP   r$   )rT   r   r   Z
last_tokenr   r   r   	_trim_end   s&    
zBlock._trim_endF)r   r   trim_endr   c           
      C  s  |dkr&||d  j dthv r&|d8 }|}t||}|d }|| j dkrb|| j tv rb|d7 }q<|| j dkr|d }|| j dkr|d7 }qxd}|d7 }|r|ddd|| j d7 }|d7 }q| ||||dd}	|r|	|S |	S n |}t||}| ||||d	dS d S )
Nr   r   r   r   r=   )r   r
   F)r$   T)r   r   rK   r   getrc   find_end)
clsr   r   rd   rN   rO   jrP   levelretr   r   r   r   	  s.    





z
Block.findN)F)__name__
__module____qualname____doc__	__slots__rU   rW   rZ   r_   ra   rc   classmethodr   r   r   r   r   rL      s   		 rL   c                 C  s<   | | j dvr|d7 }q | | j dkr0|d8 }n|d7 }|S )N>   	ENDMARKERr   r   rq   r   )r   r   r   r   r   rf   -  s    

rf   rR   )r   r   new_srcr   c                C  s   |  |tt| dS )z=
    Insert a generated token with the given new source.
    N)insertr   r   )r   r   rs   r   r   r   rt   ?  s    rt   )r   r   r   r   c                C  s   | | j t|d| |< dS )z_
    Replace the token at position i with a generated token with the given new
    source.
    r   N)r[   r   )r   r   r   r   r   r   replaceF  s    ru   ztuple[int, int]c                C  sr   t | ||d}| |d  jtkr(|d7 }| |d  jtkrB|d7 }| |d  jtkr\|d7 }t| |\}}||fS )zT
    Return bounds of tokens corresponding to the given node, minus any indent.
    r#   r   )r,   r   r   r	   LOGICAL_NEWLINEr/   )r   r   r#   rh   _r   r   r   	find_nodeN  s    ry   c                C  s$   t | ||d\}}| ||d = dS )z;
    Erase all tokens corresponding to the given node.
    rv   r   N)ry   r   r   r#   rh   r   r   r   
erase_node_  s    r{   zast.Callc                C  sP   t | ||d\}}t| |tdd}t| |td}t| |td}| ||d = dS )zx
    Specialized version of erase_node for removing decorators, since they don't
    include the @ in their bounds.
    rv   @r   rr   r   N)ry   r    r   r"   r   r   rz   r   r   r   erase_decoratori  s
    r}   )r   r   r   r`   r   c                C  s*   t | |t|d}| | jt|d| |< d S )Nr   )r   r   r[   r   )r   r   r   r`   rh   r   r   r   find_and_replace_nameu  s    r~   zdict[str, str])r   r   r#   arg_mapr   c                C  s   t | |tdd}t| |\}}|t|jd }ttt|jD ]b\}}	|	j	|v rBt
||  D ]2}
| |
 j|	j	kr`| |
 j||	j	 d| |
<  qBq`t|	j	 dqBdS )uf   
    Update an ast.Call node’s keyword argument names, where arg_map maps old to
    new names.
    r9   r   Nr   z argument not found)r   r   rF   r>   rC   reversedlist	enumeratekeywordsargrX   r   r[   AssertionError)r   r   r#   r   rh   	func_argsrx   Zkwarg_func_argsnkeywordkr   r   r   replace_argument_namesz  s    
r   "z\")'r   )textmatch_quotesr   c                C  sF   t | }td|}|dus J |d dkrB|d dkrB|t}|S )z
    Give the repr of a string, switching it to double quotes if the string
    literal represent in match_quotes uses double quotes.
    z[\'"]Nr   r   )reprresearch	translatestr_repr_single_to_double)r   r   resultZfirst_quoter   r   r   str_repr_matching  s    
r   zast.ImportFrom)r   r   r#   name_mapr   c             	   C  s   t | |tdd}t | |tdd}dd |jD }g }d}t|jD ]z\}}	|	j|vrd}t | |t|	jd}|	jdurBt | |td	d}t | |t|	jd}qB||	j }
|
d
ks|
|v rt | |t|	jd}|}|	jdurt | |td	d}t | |t|	jd}t|jdkr4|dkr$t | |tdd}nt| |tdd}t	| |t
d}t	| |td}t| ||rn|d8 }|d7 }|||g f |}qBd}t | |t|	jd}|||| | jd|
dgf |}qB|rt| ||d n&t|D ]\}}}|| ||d < qdS )u   
    Replace an ast.ImportFrom node’s imported names, where name_map maps old to
    new names. If a new name entry is the empty string, remove the import.
    fromr   importc                 S  s   h | ]}|j d u r|jqS rS   )asnamer   ).0aliasr   r   r   	<setcomp>  s   z&update_import_names.<locals>.<setcomp>TFNasr-   r   r   r<   rr   r   rv   )r   r   namesr   r   r   r>   r   r    r!   r   r	   r5   r?   r[   r{   r   )r   r   r#   r   rh   Zexisting_unaliased_namesreplacementsZ
remove_allZ	alias_idxr   new_namer1   r2   replacementr   r   r   update_import_names  s\    




r   )r   r   r#   module_rewritesr   c             
   C  s   t t}i }|jD ]F}|j}||v rd||< |jrB| d|j n|}|||  | qt| |\}	}
t| |||d t|	 D ]6\}}d
t|}t| |	|
 d| d| dd qd	S )
z
    Replace import names from an ast.ImportFrom with new import statements from
    elsewhere. rewrites should map import names to the new modules they should
    be imported from.
    r-   z as )r#   r   z, zfrom z import 
)rs   N)r   r   r   r   r   r?   r/   r   r   itemsjoinsortedrt   )r   r   r#   r   Zimports_to_addr   r   r   r   rh   r.   moduler   Zjoined_namesr   r   r   update_import_modules  s    
r   )2
__future__r   astr   collectionsr   Ztokenize_rtr   r   r   r   r   r	   r
   r   rw   r   r   r4   r   r   r    r!   r"   r)   r,   r/   r5   r@   	frozensetvaluesrH   rI   rF   rK   rL   rf   rt   ru   ry   r{   r}   r~   r   r   	maketransr   r   r   r   r   r   r   r   <module>   s`   

! 
K