
    *eM                       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(dS )    )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                  r    e Zd ZdZdIdZdJdZdKd
ZdL fdZdM fdZdN fdZ	dOdZ
dPdZdQdZdR fdZdSdZdTd ZdUd"ZdVd%ZdWd'ZdXd*ZdYdZd0Zd[d3Zd\d6Zd[d7Zd[d8Zd[d9ZdId:ZdId;Zed]d=            Zed]d>            Zed]d?            Zd^dAZ ed_dC            Z!d^dDZ"dIdEZ#dIdFZ$d`dHZ% xZ&S )a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.
    returnNonec                    d| _         d| _        d| _        i | _        g | _        g | _        g | _        g | _        g | _        d S )Nr   )	block_iddisallow_redef_depth
loop_depthblock_loop_depthblocks
var_blocksrefs	num_readsscope_kindsselfs    -lib/python3.11/site-packages/mypy/renaming.py__init__zVariableRenameVisitor.__init__F   sL    $%!02!#02
 <>	/1&(    	file_noder   c                ,   |                                   |                     t                    5  |                                 5  |j        D ]}|                    |            	 ddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS z]Rename variables within a file.

        This is the main entry point to this class.
        N)clearenter_scoper   enter_blockdefsacceptr3   r7   ds      r4   visit_mypy_filez%VariableRenameVisitor.visit_mypy_file]   s   
 	

d## 	 	T%5%5%7%7 	 	^  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s5   B	 A1%B	1A5	5B	8A5	9B		BBfdefr   c                   |                                   |                     t                    5  |                                 5  |j        D ]I}|j        j        }|dk    }|                     |j        j        |           |                     |           J|j	        j	        D ]}|
                    |            	 d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nr3   )$reject_redefinition_of_vars_in_scoper;   r!   r<   	argumentsvariablenamerecord_assignment
handle_argbodyr>   )r3   rB   argrG   can_be_redefinedstmts         r4   visit_func_defz$VariableRenameVisitor.visit_func_defg   sy    	11333h'' 
	" 
	")9)9);); 
	" 
	"~ & &|( $(6> &&s|'8:JKKK%%%%	 " "D!!!!"
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	" 
	"s6   CA6C;CC	CC	CC#&C#cdefr
   c                    |                                   |                     t                    5  t                                          |           d d d            d S # 1 swxY w Y   d S N)rD   r;   r#   supervisit_class_defr3   rO   	__class__s     r4   rS   z%VariableRenameVisitor.visit_class_defx   s    11333e$$ 	* 	*GG##D)))	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*s   "AA#&A#blockr   c                    |                                  5  t                                          |           d d d            d S # 1 swxY w Y   d S rQ   )r<   rR   visit_block)r3   rV   rU   s     r4   rX   z!VariableRenameVisitor.visit_block}   s     	' 	'GG&&&	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	'   "AA	A	rM   r   c                    |                                  5  t                                          |           d d d            d S # 1 swxY w Y   d S rQ   )
enter_looprR   visit_while_stmtr3   rM   rU   s     r4   r\   z&VariableRenameVisitor.visit_while_stmt   s    __ 	+ 	+GG$$T***	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+rY   r   c                v   |j                             |            |                     |j        d           |j                            |            |                                 5  |j                            |            d d d            n# 1 swxY w Y   |j        r|j                            |            d S d S )NT)exprr>   analyze_lvalueindexr[   rJ   	else_bodyr3   rM   s     r4   visit_for_stmtz$VariableRenameVisitor.visit_for_stmt   s    	DJ---
$__ 	# 	#IT"""	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#> 	(N!!$'''''	( 	(s   $BBBr	   c                .    |                                   d S rQ   #reject_redefinition_of_vars_in_looprc   s     r4   visit_break_stmtz&VariableRenameVisitor.visit_break_stmt       0022222r6   r   c                .    |                                   d S rQ   rf   rc   s     r4   visit_continue_stmtz)VariableRenameVisitor.visit_continue_stmt   ri   r6   r   c                    |                                  5  t                                          |           d d d            d S # 1 swxY w Y   d S rQ   )	enter_tryrR   visit_try_stmtr]   s     r4   rn   z$VariableRenameVisitor.visit_try_stmt   s     ^^ 	) 	)GG""4(((	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)rY   r   c                    |j         D ]}|                    |            |j        D ]}||                     |           |j                            |            d S rQ   )r_   r>   targetr`   rJ   )r3   rM   r_   rp   s       r4   visit_with_stmtz%VariableRenameVisitor.visit_with_stmt   sr    I 	 	DKKk 	, 	,F!##F+++ 		r6   impr   c                P    |j         D ]\  }}|                     |p|d           d S NF)idsrH   r3   rr   idas_ids       r4   visit_importz"VariableRenameVisitor.visit_import   s>     	7 	7IB""5;B6666	7 	7r6   r   c                P    |j         D ]\  }}|                     |p|d           d S rt   )namesrH   rv   s       r4   visit_import_fromz'VariableRenameVisitor.visit_import_from   s>     	7 	7IB""5;B6666	7 	7r6   sr   c                x    |j                             |            |j        D ]}|                     |           d S rQ   )rvaluer>   lvaluesr`   )r3   r}   lvalues      r4   visit_assignment_stmtz+VariableRenameVisitor.visit_assignment_stmt   sH    	i 	( 	(F''''	( 	(r6   r   c                   |j                             |            t          t          |j                            D ]}|                                 5  |j        |                             |            |j        |         }||                    |            |j        |         j        D ]}|                    |            	 d d d            n# 1 swxY w Y   d S rQ   )	subjectr>   rangelenpatternsr<   guardsbodiesrJ   )r3   r}   iguardrM   s        r4   visit_match_stmtz&VariableRenameVisitor.visit_match_stmt   s   		s1:'' 	& 	&A!!## & &
1$$T***$LL&&&HQK, & &DKK%%%%&& & & & & & & & & & & & & & &	& 	&s   A/CC	C	pr   c                L    |j         |                     |j                    d S d S rQ   )rG   r`   )r3   r   s     r4   visit_capture_patternz+VariableRenameVisitor.visit_capture_pattern   s.    6''''' r6   Fr   r   	is_nestedboolc                   t          |t                    re|j        }|                     |d          }|r|                     |           n|                     |           |r|                     |           dS dS t          |t          t          f          r#|j	        D ]}| 
                    |d           dS t          |t                    r|j                            |            dS t          |t                    r6|j                            |            |j                            |            dS t          |t"                    r| 
                    |j        |           dS dS )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)r   N)
isinstancer   rG   rH   
handle_defhandle_refine
handle_refr   r   itemsr`   r   r_   r>   r   basera   r   )r3   r   r   rG   is_newitems         r4   r`   z$VariableRenameVisitor.analyze_lvalue   s    fh'' 	B;D++D$77F +''''""6*** ( '''''( ( 9 566 	B : :##DD#9999: :
++ 	BKt$$$$$	** 	BKt$$$L%%%%%)) 	B yAAAAA	B 	Br6   r_   r   c                0    |                      |           d S rQ   )r   )r3   r_   s     r4   visit_name_exprz%VariableRenameVisitor.visit_name_expr   s    r6   rG   strc                H    g g| j         d         |<   d| j        d         |<   dS )zStore function argument.r   N)r/   r0   r3   rG   s     r4   rI   z VariableRenameVisitor.handle_arg   s+    !d	"d#$r4   r6   c                    |j         }| j        d                             |g           }|                    |g           d| j        d         |<   dS )zStore new name definition.r   r   N)rG   r/   
setdefaultappendr0   r3   r_   rG   r{   s       r4   r   z VariableRenameVisitor.handle_def   sO    y	"((r22dV#$r4   r6   c                    |j         }|| j        d         v rG| j        d         |         }|s|                    g            |d                             |           dS dS )zLStore assignment to an existing name (that replaces previous value, if any).r   N)rG   r/   r   r   s       r4   r   z#VariableRenameVisitor.handle_refine   sj    y49R=  IbM$'E !R   "IT"""""	 ! r6   c                   |j         }|| j        d         v rE| j        d         |         }|s|                    g            |d                             |           | j        d         }|                    |d          dz   ||<   dS )z Store reference to defined name.r   r   r    N)rG   r/   r   r0   get)r3   r_   rG   r{   r0   s        r4   r   z VariableRenameVisitor.handle_ref   s    y49R=  IbM$'E !R   "IT"""N2&	#--a0014	$r6   c                N   | j         d         t          k    }| j        d                                         D ]U\  }}t	          |          dk    r|r|dd         }n
|dd         }t          |          D ]\  }}t          ||           V| j                                         dS )zlRename all references within the current scope.

        This will be called at the end of a scope.
        r   r    N)r1   r!   r/   r   r   	enumeraterename_refspop)r3   is_funcrG   r/   	to_renamer   r   s          r4   
flush_refsz VariableRenameVisitor.flush_refs  s    
 "2&(2)B---// 	% 	%JD$4yyA~~ & !H		 !"I	$Y// % %4D!$$$$%	r6   c                "    g | _         g | _        d S rQ   )r-   r.   r2   s    r4   r:   zVariableRenameVisitor.clear#  s    r6   Iterator[None]c              #    K   | xj         dz  c_         | j                            | j                    | j        | j        | j         <   	 d V  | j                                         d S # | j                                         w xY wNr    )r)   r-   r   r+   r,   r   r2   s    r4   r<   z!VariableRenameVisitor.enter_block'  s}      4=)))/3dm,	EEEKOODKOOs   A& &Bc              #  ~   K   | xj         dz  c_         	 d V  | xj         dz  c_         d S # | xj         dz  c_         w xY wr   )r*   r2   s    r4   rm   zVariableRenameVisitor.enter_try1  sb      !!Q&!!	+EEE%%*%%%%D%%*%%%%%%   * <c              #  ~   K   | xj         dz  c_         	 d V  | xj         dz  c_         d S # | xj         dz  c_         w xY wr   )r+   r2   s    r4   r[   z VariableRenameVisitor.enter_loop9  sP      1	!EEEOOq OOOODOOq OOOOOOr   intc                    | j         d         S Nr   )r-   r2   s    r4   current_blockz#VariableRenameVisitor.current_blockA  s    {2r6   kindc              #  j  K   | j                             i            | j                            i            | j                            i            | j                            |           	 d V  |                                  | j                                          | j                                         | j                                         d S # |                                  | j                                          | j                                         | j                                         w xY wrQ   )r.   r   r/   r0   r1   r   r   )r3   r   s     r4   r;   z!VariableRenameVisitor.enter_scopeD  s     r"""	b!!!%%%	#EEEOOO!!!N     """"" OOO!!!N     """"s   ,C A!D2c                2    t          | j                  dk    S r   )r   r.   r2   s    r4   r   zVariableRenameVisitor.is_nestedR  s    4?##a''r6   c                4    | j         d         }|D ]}d||<   dS )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.   )r3   r.   keys      r4   rD   z:VariableRenameVisitor.reject_redefinition_of_vars_in_scopeU  s4     _R(
 	! 	!C JsOO	! 	!r6   c                    | j         d         }|                                D ]-\  }}| j                            |          | j        k    rd||<   .dS )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+   )r3   r.   r   rV   s       r4   rg   z9VariableRenameVisitor.reject_redefinition_of_vars_in_loopf  sa      _R(
$**,, 	% 	%JC$((//4?BB"$
3	% 	%r6   rL   c                    | j         d                             |d          dk    rdS | j        dk    rd}|                                 }| j        d         }||vr|r|||<   nd||<   dS ||         |k    rdS dS )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)r0   r   r*   r   r.   )r3   rG   rL   rV   r.   s        r4   rH   z'VariableRenameVisitor.record_assignment{  s     >"!!$++q005$q(($""$$_R(
z!! & $)
4   $&
4 4&&4 5r6   r&   r'   r7   r   r&   r'   rB   r   r&   r'   rO   r
   r&   r'   )rV   r   r&   r'   )rM   r   r&   r'   )rM   r   r&   r'   )rM   r	   r&   r'   )rM   r   r&   r'   )rM   r   r&   r'   rM   r   r&   r'   rr   r   r&   r'   rr   r   r&   r'   )r}   r   r&   r'   )r}   r   r&   r'   )r   r   r&   r'   )F)r   r   r   r   r&   r'   r_   r   r&   r'   rG   r   r&   r'   r&   r   )r&   r   )r   r   r&   r   )rG   r   rL   r   r&   r   )'__name__
__module____qualname____doc__r5   rA   rN   rS   rX   r\   rd   rh   rk   rn   rq   ry   r|   r   r   r   r`   r   rI   r   r   r   r   r:   r   r<   rm   r[   r   r;   r   rD   rg   rH   __classcell__rU   s   @r4   r%   r%   '   s        <) ) ) ).   " " " ""* * * * * *
' ' ' ' ' '+ + + + + +( ( ( (3 3 3 33 3 3 3) ) ) ) ) )   7 7 7 77 7 7 7( ( ( (

& 
& 
& 
&( ( ( (B B B B B>   
% % % %
% % % %# # # #	5 	5 	5 	5   0       ^ + + + ^+ ! ! ! ^!    # # # ^#( ( ( (! ! ! !"% % % %*       r6   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d0d#Zd%d$Z xZS )1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: ...
    r&   r'   c                0    g | _         g | _        g | _        d S rQ   )
bound_varsskippedr/   r2   s    r4   r5   z%LimitedVariableRenameVisitor.__init__  s!     &( (* <>			r6   r7   r   c                    |                                  5  |j        D ]}|                    |            	 ddd           dS # 1 swxY w Y   dS r9   )r;   r=   r>   r?   s      r4   rA   z,LimitedVariableRenameVisitor.visit_mypy_file  s    
  	 	^  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s    AA
ArB   r   c                   |                                   |                                 5  |j        D ]!}|                     |j        j                   "t                                          |           d d d            d S # 1 swxY w Y   d S rQ   )rD   r;   rE   record_skippedrF   rG   rR   rN   )r3   rB   rK   rU   s      r4   rN   z+LimitedVariableRenameVisitor.visit_func_def  s    11333 	) 	)~ 7 7##CL$56666GG""4(((	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)s   ABB	BrO   r
   c                    |                                   |                                 5  t                                          |           d d d            d S # 1 swxY w Y   d S rQ   )rD   r;   rR   rS   rT   s     r4   rS   z,LimitedVariableRenameVisitor.visit_class_def  s    11333 	* 	*GG##D)))	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*s   "AA ArM   r   c                   |j         D ]}|                    |            t          | j                  }|j        D ]}||                     |           |j        D ]}|r|                    |            |j                            |            t          | j                  |k    r3| j                                         t          | j                  |k    1d S d S rQ   )r_   r>   r   r   rp   r`   rJ   r   )r3   rM   r_   old_lenrp   s        r4   rq   z,LimitedVariableRenameVisitor.visit_with_stmt  s    I 	 	DKKdo&&k 	, 	,F!##F+++k 	$ 	$F $d###	$/""W,,O!!! $/""W,,,,,,r6   r   r   c                   t          |t                    rt|j        }|| j        v r|                     |           d S | j        d         }||vrg ||<   ||                             g            | j                            |           d S t          |t          t          f          r!|j	        D ]}| 
                    |           d S t          |t                    r|j                            |            d S t          |t                    r6|j                            |            |j                            |            d S t          |t"                    r| 
                    |j                   d S d S r   )r   r   rG   r   r   r/   r   r   r   r   r`   r   r_   r>   r   r   ra   r   )r3   r   rG   var_infor   s        r4   r`   z+LimitedVariableRenameVisitor.analyze_lvalue  s   fh'' 	-;Dt&&$$V,,,,,9R=x''%'HTN%%b)))&&t,,,,,9 566 		- * *##D))))* *
++ 	-Kt$$$$$	** 	-Kt$$$L%%%%%)) 	-,,,,,	- 	-r6   rr   r   c                N    |j         D ]\  }}|                     |p|           d S rQ   )ru   r   rv   s       r4   ry   z)LimitedVariableRenameVisitor.visit_import  s<     	- 	-IB,,,,	- 	-r6   r   c                N    |j         D ]\  }}|                     |p|           d S rQ   )r{   r   rv   s       r4   r|   z.LimitedVariableRenameVisitor.visit_import_from  s<     	- 	-IB,,,,	- 	-r6   r   c                .    |                                   d S rQ   )rD   )r3   rr   s     r4   visit_import_allz-LimitedVariableRenameVisitor.visit_import_all  s    1133333r6   r_   r   c                    |j         }|| j        v r>t          | j                  D ]'}||v r!||         d                             |           (d S |                     |           d S r   )rG   r   reversedr/   r   r   )r3   r_   rG   scopes       r4   r   z,LimitedVariableRenameVisitor.visit_name_expr  s{    y4?""!$),, 1 15==$KO**40001 1 %%%%%r6   r   c              #     K   | j                             t                                 | j                            i            d V  |                                  d S rQ   )r   r   setr/   r   r2   s    r4   r;   z(LimitedVariableRenameVisitor.enter_scope  sU      CEE"""	


r6   c                0    |                      d           d S )N*)r   r2   s    r4   rD   zALimitedVariableRenameVisitor.reject_redefinition_of_vars_in_scope   s    C     r6   rG   r   c                F    | j         d                             |           d S r   )r   addr   s     r4   r   z+LimitedVariableRenameVisitor.record_skipped#  s#    RT"""""r6   c                8   | j                                         }| j                                        }d|vra|                                D ]N\  }}t	          |          dk    s||v r|d d         }t          |          D ]\  }}t          ||           Md S d S )Nr   r    r   )r/   r   r   r   r   r   r   )r3   ref_dictr   rG   r/   r   r   r   s           r4   r   z'LimitedVariableRenameVisitor.flush_refs&  s    9==??,""$$g&nn.. ) )
dt99>>TW__ !"I	(33 ) )GAta(((() ) )r6   r   r   r   r   r   )r   r   r&   r'   r   r   )rr   r   r&   r'   r   r   r   )r   r   r   r   r5   rA   rN   rS   rq   r`   ry   r|   r   r   r   r;   rD   r   r   r   r   s   @r4   r   r     sa        :
> 
> 
> 
>   ) ) ) ) ) )* * * * * *
" " " "- - - -.- - - -
- - - -
4 4 4 4& & & &    ^! ! ! !# # # #) ) ) ) ) ) ) )r6   r   r{   list[NameExpr]ra   r   r&   r'   c                N    | d         j         }|d|dz   z  z   }| D ]	}||_         
d S )Nr   'r    )rG   )r{   ra   rG   new_namer_   s        r4   r   r   4  sB    8=DcUQY''H  		 r6   N)r{   r   ra   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    r6   r4   <module>r      s   " " " " " " " % % % % % % " " " " " " " "                                               0 $ # # # # # + + + + + +         r r r r r, r r rjU) U) U) U) U)#3 U) U) U)p     r6   