
    %^gM                       U d dl mZ d dlmZ d dlmZmZ d dlmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZ d dl m!Z! d Z"de#d<   d	Z$de#d
<   dZ%de#d<    G d de!      Z& G d de!      Z'ddZ(y)    )annotations)contextmanager)FinalIterator)AssignmentStmtBlock	BreakStmtClassDefContinueStmtForStmtFuncDefImport	ImportAll
ImportFrom	IndexExprListExprLvalue	MatchStmt
MemberExprMypyFileNameExprStarExprTryStmt	TupleExpr	WhileStmtWithStmt)	AsPattern)TraverserVisitorr   FILE   FUNCTION   CLASSc                  Z    e Zd ZdZd#dZd$dZd%dZd& fdZd' fdZd( fdZ	d)dZ
d*d	Zd+d
Zd, fdZd-dZd.dZd/dZd0dZd1dZd2dZd3d4dZd5dZd6dZd5dZd5dZd5dZd#dZd#dZed7d       Zed7d       Zed7d       Zd8dZ ed9d       Z!d8dZ"d#d Z#d#d!Z$d:d"Z% xZ&S );VariableRenameVisitora  Rename variables to allow redefinition of variables.

    For example, consider this code:

      x = 0
      f(x)

      x = "a"
      g(x)

    It will be transformed like this:

      x' = 0
      f(x')

      x = "a"
      g(x)

    There will be two independent variables (x' and x) that will have separate
    inferred types. The publicly exposed variant will get the non-suffixed name.
    This is the last definition at module top level and the first definition
    (argument) within a function.

    Renaming only happens for assignments within the same block. Renaming is
    performed before semantic analysis, immediately after parsing.

    The implementation performs a rudimentary static analysis. The analysis is
    overly conservative to keep things simple.
    c                    d| _         d| _        d| _        i | _        g | _        g | _        g | _        g | _        g | _        y )Nr   )	block_iddisallow_redef_depth
loop_depthblock_loop_depthblocks
var_blocksrefs	num_readsscope_kindsselfs    -lib/python3.12/site-packages/mypy/renaming.py__init__zVariableRenameVisitor.__init__F   sF    $%!02!#02
 <>	/1&(    c                   | j                          | j                  t              5  | j                         5  |j                  D ]  }|j                  |         	 ddd       ddd       y# 1 sw Y   xY w# 1 sw Y   yxY wz]Rename variables within a file.

        This is the main entry point to this class.
        N)clearenter_scoper   enter_blockdefsacceptr1   	file_nodeds      r2   visit_mypy_filez%VariableRenameVisitor.visit_mypy_file]   sX    
 	

d#T%5%5%7^^ $ &8##%7%7##s"   A8#A,A8,A5	1A88Bc                   | j                          | j                  t              5  | j                         5  |j                  D ]T  }|j
                  j                  }|dk7  }| j                  |j
                  j                  |       | j                  |       V |j                  j                  D ]  }|j                  |         	 d d d        d d d        y # 1 sw Y   xY w# 1 sw Y   y xY w)Nr1   )$reject_redefinition_of_vars_in_scoper8   r!   r9   	argumentsvariablenamerecord_assignment
handle_argbodyr;   )r1   fdefargrD   can_be_redefinedstmts         r2   visit_func_defz$VariableRenameVisitor.visit_func_defg   s     	113h')9)9);~~||(( $(6> &&s||'8'8:JK% & 		D! ' *<''););''s#   C%BCC%C"	C%%C.c                    | j                          | j                  t              5  t        |   |       d d d        y # 1 sw Y   y xY wN)rA   r8   r#   supervisit_class_defr1   cdef	__class__s     r2   rP   z%VariableRenameVisitor.visit_class_defx   s6    113e$G#D) %$$s   A  A	c                n    | j                         5  t        | 	  |       d d d        y # 1 sw Y   y xY wrN   )r9   rO   visit_block)r1   blockrS   s     r2   rU   z!VariableRenameVisitor.visit_block}   s(    G&     +4c                n    | j                         5  t        | 	  |       d d d        y # 1 sw Y   y xY wrN   )
enter_looprO   visit_while_stmtr1   rK   rS   s     r2   rZ   z&VariableRenameVisitor.visit_while_stmt   s&    __G$T* rW   c                x   |j                   j                  |        | j                  |j                  d       |j                  j                  |        | j	                         5  |j
                  j                  |        d d d        |j                  r|j                  j                  |        y y # 1 sw Y   2xY w)NT)exprr;   analyze_lvalueindexrY   rG   	else_bodyr1   rK   s     r2   visit_for_stmtz$VariableRenameVisitor.visit_for_stmt   s    		DJJ-

$__IIT" >>NN!!$'  s   #B00B9c                $    | j                          y rN   #reject_redefinition_of_vars_in_loopra   s     r2   visit_break_stmtz&VariableRenameVisitor.visit_break_stmt       002r4   c                $    | j                          y rN   rd   ra   s     r2   visit_continue_stmtz)VariableRenameVisitor.visit_continue_stmt   rg   r4   c                n    | j                         5  t        | 	  |       d d d        y # 1 sw Y   y xY wrN   )	enter_tryrO   visit_try_stmtr[   s     r2   rl   z$VariableRenameVisitor.visit_try_stmt   s(     ^^G"4( rW   c                    |j                   D ]  }|j                  |         |j                  D ]  }|| j                  |        |j                  j                  |        y rN   )r]   r;   targetr^   rG   )r1   rK   r]   rn   s       r2   visit_with_stmtz%VariableRenameVisitor.visit_with_stmt   sR    IIDKK kkF!##F+ " 			r4   c                X    |j                   D ]  \  }}| j                  |xs |d        y NF)idsrE   r1   impidas_ids       r2   visit_importz"VariableRenameVisitor.visit_import   s(    IB""5;B6 !r4   c                X    |j                   D ]  \  }}| j                  |xs |d        y rq   )namesrE   rs   s       r2   visit_import_fromz'VariableRenameVisitor.visit_import_from   s(    IB""5;B6 #r4   c                ~    |j                   j                  |        |j                  D ]  }| j                  |        y rN   )rvaluer;   lvaluesr^   )r1   slvalues      r2   visit_assignment_stmtz+VariableRenameVisitor.visit_assignment_stmt   s.    	iiF'  r4   c                   |j                   j                  |        t        t        |j                              D ]  }| j                         5  |j                  |   j                  |        |j                  |   }||j                  |        |j                  |   j                  D ]  }|j                  |         	 d d d         y # 1 sw Y   xY wrN   )	subjectr;   rangelenpatternsr9   guardsbodiesrG   )r1   r~   iguardrK   s        r2   visit_match_stmtz&VariableRenameVisitor.visit_match_stmt   s    			s1::'A!!#

1$$T*$LL&HHQK,,DKK% - $# (##s   A0C		C	c                T    |j                   | j                  |j                          y y rN   )rD   r^   )r1   ps     r2   visit_capture_patternz+VariableRenameVisitor.visit_capture_pattern   s#    66' r4   c                   t        |t              rX|j                  }| j                  |d      }|r| j	                  |       n| j                  |       |r| j                  |       yyt        |t        t        f      r%|j                  D ]  }| j                  |d        yt        |t              r|j                  j                  |        yt        |t              r7|j                  j                  |        |j                   j                  |        yt        |t"              r| j                  |j                  |       yy)zProcess assignment; in particular, keep track of (re)defined names.

        Args:
            is_nested: True for non-outermost Lvalue in a multiple assignment such as
                "x, y = ..."
        T)	is_nestedN)
isinstancer   rD   rE   
handle_defhandle_refine
handle_refr   r   itemsr^   r   r]   r;   r   baser_   r   )r1   r   r   rD   is_newitems         r2   r^   z$VariableRenameVisitor.analyze_lvalue   s     fh';;D++D$7F'""6* '  9 56##DD#9 %
+KKt$	*KKt$LL%) yA *r4   c                &    | j                  |       y rN   )r   )r1   r]   s     r2   visit_name_exprz%VariableRenameVisitor.visit_name_expr   s    r4   c                N    g g| j                   d   |<   d| j                  d   |<   y)zStore function argument.r   N)r-   r.   r1   rD   s     r2   rF   z VariableRenameVisitor.handle_arg   s)    !d		"d#$r4 r4   c                    |j                   }| j                  d   j                  |g       }|j                  |g       d| j                  d   |<   y)zStore new name definition.r   r   N)rD   r-   
setdefaultappendr.   r1   r]   rD   ry   s       r2   r   z VariableRenameVisitor.handle_def   sF    yy		"((r2dV#$r4 r4   c                    |j                   }|| j                  d   v r:| j                  d   |   }|s|j                  g        |d   j                  |       yy)zLStore assignment to an existing name (that replaces previous value, if any).r   N)rD   r-   r   r   s       r2   r   z#VariableRenameVisitor.handle_refine   sS    yy499R= IIbM$'ER "IT"	 !r4   c                    |j                   }|| j                  d   v r9| j                  d   |   }|s|j                  g        |d   j                  |       | j                  d   }|j	                  |d      dz   ||<   y)z Store reference to defined name.r   r   r    N)rD   r-   r   r.   get)r1   r]   rD   ry   r.   s        r2   r   z VariableRenameVisitor.handle_ref   su    yy499R= IIbM$'ER "IT"NN2&	#--a014	$r4   c                   | j                   d   t        k(  }| j                  d   j                         D ]=  }t	        |      dk(  r|r|dd }n|dd }t        |      D ]  \  }}t        ||        ? | j                  j                          y)zlRename all references within the current scope.

        This will be called at the end of a scope.
        r   r    N)r/   r!   r-   valuesr   	enumeraterename_refspop)r1   is_funcr-   	to_renamer   r   s         r2   
flush_refsz VariableRenameVisitor.flush_refs  s    
 ""2&(2IIbM((*D4yA~ !H	 !"I	$Y/4D!$ 0 + 			r4   c                     g | _         g | _        y rN   )r+   r,   r0   s    r2   r7   zVariableRenameVisitor.clear#  s    r4   c              #  B  K   | xj                   dz  c_         | j                  j                  | j                          | j                  | j                  | j                   <   	 d  | j                  j                          y # | j                  j                          w xY wwNr    )r'   r+   r   r)   r*   r   r0   s    r2   r9   z!VariableRenameVisitor.enter_block'  sf     4==)/3dmm,	KKOODKKOOs   AB!B  %B BBc              #     K   | xj                   dz  c_         	 d  | xj                   dz  c_         y # | xj                   dz  c_         w xY wwr   )r(   r0   s    r2   rk   zVariableRenameVisitor.enter_try1  sA     !!Q&!	+%%*%D%%*%   A3 AA

Ac              #     K   | xj                   dz  c_         	 d  | xj                   dz  c_         y # | xj                   dz  c_         w xY wwr   )r)   r0   s    r2   rY   z VariableRenameVisitor.enter_loop9  s8     1	!OOq ODOOq Or   c                     | j                   d   S Nr   )r+   r0   s    r2   current_blockz#VariableRenameVisitor.current_blockA  s    {{2r4   c              #  p  K   | j                   j                  i        | j                  j                  i        | j                  j                  i        | j                  j                  |       	 d  | j                          | j                   j                          | j                  j                          | j                  j                          y # | j                          | j                   j                          | j                  j                          | j                  j                          w xY wwrN   )r,   r   r-   r.   r/   r   r   )r1   kinds     r2   r8   z!VariableRenameVisitor.enter_scopeD  s     r"		b!%	#OOOO!NN   " OOOO!NN   "s    A-D60C 4AD6A D33D6c                2    t        | j                        dkD  S r   )r   r,   r0   s    r2   r   zVariableRenameVisitor.is_nestedR  s    4??#a''r4   c                :    | j                   d   }|D ]  }d||<   	 y)a_  Make it impossible to redefine defined variables in the current scope.

        This is used if we encounter a function definition that
        can make it ambiguous which definition is live. Example:

          x = 0

          def f() -> int:
              return x

          x = ''  # Error -- cannot redefine x across function definition
        r   N)r,   )r1   r,   keys      r2   rA   z:VariableRenameVisitor.reject_redefinition_of_vars_in_scopeU  s%     __R(
C JsO r4   c                    | j                   d   }|j                         D ]3  \  }}| j                  j                  |      | j                  k(  s/d||<   5 y)a  Reject redefinition of variables in the innermost loop.

        If there is an early exit from a loop, there may be ambiguity about which
        value may escape the loop. Example where this matters:

          while f():
              x = 0
              if g():
                  break
              x = ''  # Error -- not a redefinition
          reveal_type(x)  # int

        This method ensures that the second assignment to 'x' doesn't introduce a new
        variable.
        r   N)r,   r   r*   r   r)   )r1   r,   r   rV   s       r2   re   z9VariableRenameVisitor.reject_redefinition_of_vars_in_loopf  sO      __R(
$**,JC$$((/4??B"$
3 -r4   c                    | j                   d   j                  |d      dk(  ry| j                  dkD  rd}| j                         }| j                  d   }||vr|r|||<   yd||<   y||   |k(  ryy)zRecord assignment to given name and return True if it defines a new variable.

        Args:
            can_be_redefined: If True, allows assignment in the same block to redefine
                this name (if this is a new definition)
        r   r   FT)r.   r   r(   r   r,   )r1   rD   rJ   rV   r,   s        r2   rE   z'VariableRenameVisitor.record_assignment{  s     >>"!!$+q0$$q($""$__R(
z! $)
4   $&
4 & r4   returnNoner=   r   r   r   rH   r   r   r   rR   r
   r   r   )rV   r   r   r   )rK   r   r   r   )rK   r   r   r   )rK   r	   r   r   )rK   r   r   r   )rK   r   r   r   rK   r   r   r   rt   r   r   r   rt   r   r   r   )r~   r   r   r   )r~   r   r   r   )r   r   r   r   )F)r   r   r   boolr   r   r]   r   r   r   rD   strr   r   r   Iterator[None])r   int)r   r   r   r   )rD   r   rJ   r   r   r   )'__name__
__module____qualname____doc__r3   r?   rL   rP   rU   rZ   rb   rf   ri   rl   ro   rw   rz   r   r   r   r^   r   rF   r   r   r   r   r7   r   r9   rk   rY   r   r8   r   rA   re   rE   __classcell__rS   s   @r2   r%   r%   '   s    <).""*
'+(33)77(

&(B>
%
%#	50   + + ! ! # #(!"%*r4   r%   c                       e Zd ZdZddZddZd fdZd fdZddZddZ	ddZ
dd	Zdd
ZddZedd       ZddZddZddZ xZS )LimitedVariableRenameVisitora|  Perform some limited variable renaming in with statements.

    This allows reusing a variable in multiple with statements with
    different types. For example, the two instances of 'x' can have
    incompatible types:

       with C() as x:
           f(x)
       with D() as x:
           g(x)

    The above code gets renamed conceptually into this (not valid Python!):

       with C() as x':
           f(x')
       with D() as x:
           g(x)

    If there's a reference to a variable defined in 'with' outside the
    statement, or if there's any trickiness around variable visibility
    (e.g. function definitions), we give up and won't perform renaming.

    The main use case is to allow binding both readable and writable
    binary files into the same variable. These have different types:

        with open(fnam, 'rb') as f: ...
        with open(fnam, 'wb') as f: ...
    c                .    g | _         g | _        g | _        y rN   )
bound_varsskippedr-   r0   s    r2   r3   z%LimitedVariableRenameVisitor.__init__  s     &( (* <>	r4   c                    | j                         5  |j                  D ]  }|j                  |         	 ddd       y# 1 sw Y   yxY wr6   )r8   r:   r;   r<   s      r2   r?   z,LimitedVariableRenameVisitor.visit_mypy_file  s5    
 ^^ $  s	   #>Ac                    | j                          | j                         5  |j                  D ]'  }| j                  |j                  j
                         ) t        |   |       d d d        y # 1 sw Y   y xY wrN   )rA   r8   rB   record_skippedrC   rD   rO   rL   )r1   rH   rI   rS   s      r2   rL   z+LimitedVariableRenameVisitor.visit_func_def  sZ    113~~##CLL$5$56 &G"4(  s   AA11A:c                    | j                          | j                         5  t        |   |       d d d        y # 1 sw Y   y xY wrN   )rA   r8   rO   rP   rQ   s     r2   rP   z,LimitedVariableRenameVisitor.visit_class_def  s4    113G#D)  s	   ;Ac                   |j                   D ]  }|j                  |         t        | j                        }|j                  D ]  }|| j                  |        |j                  D ]  }|s|j                  |         |j                  j                  |        t        | j                        |kD  r4| j                  j                          t        | j                        |kD  r3y y rN   )r]   r;   r   r   rn   r^   rG   r   )r1   rK   r]   old_lenrn   s        r2   ro   z,LimitedVariableRenameVisitor.visit_with_stmt  s    IIDKK doo&kkF!##F+ " kkFd# " 			$//"W,OO! $//"W,r4   c                   t        |t              rt|j                  }|| j                  v r| j	                  |       y | j
                  d   }||vrg ||<   ||   j                  g        | j                  j                  |       y t        |t        t        f      r#|j                  D ]  }| j                  |        y t        |t              r|j                  j                  |        y t        |t              r7|j                  j                  |        |j                   j                  |        y t        |t"              r| j                  |j                         y y r   )r   r   rD   r   r   r-   r   r   r   r   r^   r   r]   r;   r   r   r_   r   )r1   r   rD   var_infor   s        r2   r^   z+LimitedVariableRenameVisitor.analyze_lvalue  s   fh';;Dt&$$V,99R=x'%'HTN%%b)&&t,9 56##D) %
+KKt$	*KKt$LL%), *r4   c                V    |j                   D ]  \  }}| j                  |xs |        y rN   )rr   r   rs   s       r2   rw   z)LimitedVariableRenameVisitor.visit_import  s&    IB, !r4   c                V    |j                   D ]  \  }}| j                  |xs |        y rN   )ry   r   rs   s       r2   rz   z.LimitedVariableRenameVisitor.visit_import_from  s&    IB, #r4   c                $    | j                          y rN   )rA   )r1   rt   s     r2   visit_import_allz-LimitedVariableRenameVisitor.visit_import_all  s    113r4   c                    |j                   }|| j                  v r7t        | j                        D ]  }||v s||   d   j	                  |         y | j                  |       y r   )rD   r   reversedr-   r   r   )r1   r]   rD   scopes       r2   r   z,LimitedVariableRenameVisitor.visit_name_expr  sW    yy4??"!$)),5=$KO**40 - %r4   c              #     K   | j                   j                  t                      | j                  j                  i        d  | j	                          y wrN   )r   r   setr-   r   r0   s    r2   r8   z(LimitedVariableRenameVisitor.enter_scope  s;     CE"		
s   AAc                &    | j                  d       y )N*)r   r0   s    r2   rA   zALimitedVariableRenameVisitor.reject_redefinition_of_vars_in_scope   s    C r4   c                @    | j                   d   j                  |       y r   )r   addr   s     r2   r   z+LimitedVariableRenameVisitor.record_skipped#  s    RT"r4   c                   | j                   j                         }| j                  j                         }d|vrP|j                         D ]<  \  }}t	        |      dk  s||v r|d d }t        |      D ]  \  }}t        ||        > y y )Nr   r    r   )r-   r   r   r   r   r   r   )r1   ref_dictr   rD   r-   r   r   r   s           r2   r   z'LimitedVariableRenameVisitor.flush_refs&  s    99==?,,""$g&nn.
dt9>TW_ !"I	(3GAta(  4 / r4   r   r   r   r   r   )r   r   r   r   r   r   )rt   r   r   r   r   r   r   )r   r   r   r   r3   r?   rL   rP   ro   r^   rw   rz   r   r   r   r8   rA   r   r   r   r   s   @r2   r   r     s]    :
>)*
"-.-
-
4&  !#)r4   r   c                T    | d   j                   }|d|dz   z  z   }| D ]	  }||_          y )Nr   'r    )rD   )ry   r_   rD   new_namer]   s        r2   r   r   4  s3    8==DcUQY''H	 r4   N)ry   zlist[NameExpr]r_   r   r   r   ))
__future__r   
contextlibr   typingr   r   
mypy.nodesr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   mypy.patternsr   mypy.traverserr   r   __annotations__r!   r#   r%   r   r    r4   r2   <module>r      sx    " % "     0 $ + e% u r, rjU)#3 U)pr4   