ML iP UddlmZddlmZddlmZddlmZddlm Z m Z m Z m Z m Z mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZddlm Z ddl!m"Z"dZ#de$d <d Z%de$d <d Z&de$d <Gdde"Z'Gdde"Z(ddZ)y)) annotations)Iterator)contextmanager)Final)AssignmentStmtBlock BreakStmtClassDef ContinueStmtForStmtFuncDefImport ImportAll ImportFrom IndexExprListExprLvalue MatchStmt MemberExprMypyFileNameExprStarExprTryStmt TupleExpr WhileStmtWithStmt) AsPattern)TraverserVisitorrFILEFUNCTIONCLASScVeZdZdZd#dZd$dZd%dZd&fd Zd'fd Zd(fd Z d)dZ d*d Z d+d Z d,d Z d-d Zd.d Zd/dZd0dZd1dZd2dZd3d4dZd5dZd6dZd5dZd5dZd5dZd#dZd#dZed7dZed7dZed7dZd8dZ ed9dZ!d8dZ"d#d Z#d#d!Z$d:d"Z%xZ&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. cd|_d|_d|_i|_g|_g|_g|_g|_g|_y)Nr) block_iddisallow_redef_depth loop_depthblock_loop_depthblocks var_blocksrefs num_reads scope_kindsselfs S/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/mypy/renaming.py__init__zVariableRenameVisitor.__init__GsF $%!02!# 02 <> /1&(c|j|jt5|j5|jD]}|j | ddddddy#1swYxYw#1swYyxYwz]Rename variables within a file. This is the main entry point to this class. N)clear enter_scoper enter_blockdefsacceptr1 file_nodeds r2visit_mypy_filez%VariableRenameVisitor.visit_mypy_file^sn   d # T%5%5%7 ^^        s"A8#A,A8,A5 1A88Bc|j|jt5|j5|jD]T}|j j }|dk7}|j|j j ||j|V|jjD]}|j| ddddddy#1swYxYw#1swYyxYw)Nr1) $reject_redefinition_of_vars_in_scoper8r!r9 argumentsvariablenamerecord_assignment handle_argbodyr;)r1fdefargrDcan_be_redefinedstmts r2visit_func_defz$VariableRenameVisitor.visit_func_defhs 113   h ' ")9)9); "~~ &||(($(6> &&s||'8'8:JK%  &  " D! " " " " " " "s#C%BCC%C" C%%C.c|j|jt5t||dddy#1swYyxYwN)rAr8r#supervisit_class_defr1cdef __class__s r2rPz%VariableRenameVisitor.visit_class_defys? 113   e $ * G #D ) * * *s AA cn|j5t| |dddy#1swYyxYwrN)r9rO visit_block)r1blockrSs r2rUz!VariableRenameVisitor.visit_block~s1     ' G  & ' ' '+4cn|j5t| |dddy#1swYyxYwrN) enter_looprOvisit_while_stmt)r1rKrSs r2rZz&VariableRenameVisitor.visit_while_stmts/ __  + G $T * + + +rWcx|jj||j|jd|jj||j 5|j j|ddd|j r|j j|yy#1swY2xYw)NT)exprr;analyze_lvalueindexrYrG else_bodyr1rKs r2visit_for_stmtz$VariableRenameVisitor.visit_for_stmts  DJJ- $ __  # II  T " # >> NN ! !$ '  # #s #B00B9c$|jyrN#reject_redefinition_of_vars_in_loopr`s r2visit_break_stmtz&VariableRenameVisitor.visit_break_stmt 002r4c$|jyrNrcr`s r2visit_continue_stmtz)VariableRenameVisitor.visit_continue_stmtrfr4cf|j5|jj|dddt|j|j |j D]h\}}}|j5||j|||j||jD]}|j| dddj|j|jj||j|jj|yy#1swYxYw#1swYxYwrN) enter_tryrGr;zipvarstypeshandlersr9 handle_defr_ finally_body)r1rKvartphandlerss r2visit_try_stmtz$VariableRenameVisitor.visit_try_stmts ^^  # II  T " #!$DIItzz4== I # CW!!# #>IIdO?OOC( #AHHTN#  # # # >> % NN ! !$ '    (    $ $T * ) # # # #sD7A D'D$'D0 c|jD]}|j||jD]}||j||jj|yrN)r\r;targetr]rG)r1rKr\rws r2visit_with_stmtz%VariableRenameVisitor.visit_with_stmts\II D KK  kk ,F!##F+ , r4cX|jD]\}}|j|xs|dyNF)idsrEr1impidas_ids r2 visit_importz"VariableRenameVisitor.visit_imports- 7IB  " "5;B 6 7r4cX|jD]\}}|j|xs|dyrz)namesrEr|s r2visit_import_fromz'VariableRenameVisitor.visit_import_froms- 7IB  " "5;B 6 7r4c~|jj||jD]}|j|yrN)rvaluer;lvaluesr])r1rtlvalues r2visit_assignment_stmtz+VariableRenameVisitor.visit_assignment_stmts3 ii (F    ' (r4c|jj|tt|jD]}|j 5|j|j||j |}||j||j|jD]}|j| dddy#1swYxYwrN) subjectr;rangelenpatternsr9guardsbodiesrG)r1rtiguardrKs r2visit_match_stmtz&VariableRenameVisitor.visit_match_stmts s1::' &A!!# & 1 $$T* $LL&HHQK,,&DKK%&  & & & & &s A0C  C cT|j|j|jyyrN)rDr])r1ps r2visit_capture_patternz+VariableRenameVisitor.visit_capture_patterns# 66     ' r4ct|trX|j}|j|d}|r|j |n|j ||r|j |yyt|ttfr%|jD]}|j|dyt|tr|jj|yt|tr7|jj||j j|yt|t"r|j|j|yy)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) isinstancerrDrEro handle_refine handle_refrritemsr]rr\r;rbaser^r)r1rrrDis_newitems r2r]z$VariableRenameVisitor.analyze_lvalues fh ';;D++D$7F'""6*'9 5 6  :##DD#9 :  + KK  t $  * KK  t $ LL   %  )    y  A*r4c&|j|yrN)r)r1r\s r2visit_name_exprz%VariableRenameVisitor.visit_name_exprs r4cNgg|jd|<d|jd|<y)zStore function argument.rN)r-r.r1rDs r2rFz VariableRenameVisitor.handle_args)!d " d#$r4 r4c|j}|jdj|g}|j|gd|jd|<y)zStore new name definition.rrN)rDr- setdefaultappendr.r1r\rDrs r2roz VariableRenameVisitor.handle_defsFyy " ((r2 dV#$r4 r4c|j}||jdvr:|jd|}|s|jg|dj|yy)zLStore assignment to an existing name (that replaces previous value, if any).rN)rDr-rrs r2rz#VariableRenameVisitor.handle_refinesSyy 499R= IIbM$'E R "I  T " !r4c|j}||jdvr9|jd|}|s|jg|dj||jd}|j |ddz||<y)z Store reference to defined name.rrr N)rDr-rr.get)r1r\rDrr.s r2rz VariableRenameVisitor.handle_refsuyy 499R= IIbM$'E R "I  T "NN2& #--a014 $r4c|jdtk(}|jdjD]=}t |dk(r|r|dd}n|dd}t |D]\}}t ||?|jjy)zlRename all references within the current scope. This will be called at the end of a scope. rr N)r/r!r-valuesr enumerate rename_refspop)r1is_funcr- to_renamerrs r2 flush_refsz VariableRenameVisitor.flush_refss ""2&(2IIbM((* %D4yA~!H !"I $Y/ %4D!$ % % r4c g|_g|_yrN)r+r,r0s r2r7zVariableRenameVisitor.clear2s r4c#BK|xjdz c_|jj|j|j|j|j< d|jj y#|jj wxYwwNr )r'r+rr)r*rr0s r2r9z!VariableRenameVisitor.enter_block6sf   4==)/3dmm,   KKOO DKKOO sAB!B%BBBc#K|xjdz c_ d|xjdzc_y#|xjdzc_wxYwwr)r(r0s r2rjzVariableRenameVisitor.enter_try@sA !!Q&! +   % % * %D % % * %A 3A A  A c#K|xjdz c_ d|xjdzc_y#|xjdzc_wxYwwr)r)r0s r2rYz VariableRenameVisitor.enter_loopHs8 1 !  OOq ODOOq Orc |jdSNr)r+r0s r2 current_blockz#VariableRenameVisitor.current_blockPs{{2r4c#pK|jji|jji|jji|jj| d|j |jj |jj |jj y#|j |jj |jj |jj wxYwwrN)r,rr-r.r/rr)r1kinds r2r8z!VariableRenameVisitor.enter_scopeSs r"  b! % #  OO  OO   ! NN      " OO  OO   ! NN      "s A-D60C4AD6A D33D6c2t|jdkDSr)rr,r0s r2rzVariableRenameVisitor.is_nestedas4??#a''r4c:|jd}|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 rN)r,)r1r,keys r2rAz:VariableRenameVisitor.reject_redefinition_of_vars_in_scopeds*__R(  !C JsO !r4c|jd}|jD]3\}}|jj||jk(s/d||<5y)aReject 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. rN)r,rr*rr))r1r,rrVs r2rdz9VariableRenameVisitor.reject_redefinition_of_vars_in_loopusT __R( $**, %JC$$((/4??B"$ 3 %r4c|jdj|ddk(ry|jdkDrd}|j}|jd}||vr|r|||<yd||<y|||k(ryy)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) rrFT)r.rr(rr,)r1rDrJrVr,s r2rEz'VariableRenameVisitor.record_assignments >>"  ! !$ +q 0  $ $q ($ ""$__R( z !$) 4 $& 4    &r4returnNoner=rrrrHr rrrRr rr)rVrrr)rKrrr)rKr rr)rKr rr)rKr rr)rKrrrrKrrrr}rrrr}rrr)rtrrr)rtrrr)rrrr)F)rrrboolrrr\rrrrDstrrrrIterator[None])rint)rrrr)rDrrJrrr)'__name__ __module__ __qualname____doc__r3r?rLrPrUrZrarerhrurxrrrrrr]rrFrorrrr7rr9rjrYrr8rrArdrE __classcell__rSs@r2r%r%(s<).""* '+(33+* 77( &(B> % %# 50++!! # #(!"%*r4r%ceZdZdZddZddZdfd Zdfd ZddZddZ ddZ dd Z dd Z dd Z edd Zdd ZddZddZxZS)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|_yrN) bound_varsskippedr-r0s r2r3z%LimitedVariableRenameVisitor.__init__s&((* <> r4c|j5|jD]}|j| dddy#1swYyxYwr6)r8r:r;r<s r2r?z,LimitedVariableRenameVisitor.visit_mypy_filesC     ^^     s #>Ac|j|j5|jD]'}|j|jj )t ||dddy#1swYyxYwrN)rAr8rBrecord_skippedrCrDrOrL)r1rHrIrSs r2rLz+LimitedVariableRenameVisitor.visit_func_defsh 113     )~~ 7##CLL$5$56 7 G "4 ( ) ) )s AA11A:c|j|j5t| |dddy#1swYyxYwrN)rAr8rOrPrQs r2rPz,LimitedVariableRenameVisitor.visit_class_defs= 113     * G #D ) * * *s ;Ac|jD]}|j|t|j}|jD]}||j ||jD]}|s|j||j j|t|j|kDr4|jjt|j|kDr3yyrN)r\r;rrrwr]rGr)r1rKr\old_lenrws r2rxz,LimitedVariableRenameVisitor.visit_with_stmtsII D KK  doo&kk ,F!##F+ ,kk $F d# $ $//"W, OO   !$//"W,r4ct|trt|j}||jvr|j |y|j d}||vrg||<||j g|jj |yt|ttfr#|jD]}|j|yt|tr|jj|yt|tr7|jj||j j|yt|t"r|j|jyyr)rrrDrrr-rrrrr]rr\r;rrr^r)r1rrDvar_infors r2r]z+LimitedVariableRenameVisitor.analyze_lvalues  fh ';;Dt&$$V,99R=x'%'HTN%%b)&&t, 9 5 6  *##D) *  + KK  t $  * KK  t $ LL   %  )    ,*r4cV|jD]\}}|j|xs|yrN)r{rr|s r2rz)LimitedVariableRenameVisitor.visit_imports+ -IB     , -r4cV|jD]\}}|j|xs|yrN)rrr|s r2rz.LimitedVariableRenameVisitor.visit_import_froms+ -IB     , -r4c$|jyrN)rA)r1r}s r2visit_import_allz-LimitedVariableRenameVisitor.visit_import_alls 113r4c|j}||jvr7t|jD]}||vs||dj | y|j |yr)rDrreversedr-rr)r1r\rDscopes r2rz,LimitedVariableRenameVisitor.visit_name_exprs\yy 4?? "!$)), 15=$KO**40 1    %r4c#K|jjt|jjid|j ywrN)rrsetr-rr0s r2r8z(LimitedVariableRenameVisitor.enter_scope(s; CE"   sAAc&|jdy)N*)rr0s r2rAzALimitedVariableRenameVisitor.reject_redefinition_of_vars_in_scope/s C r4c@|jdj|yr)raddrs r2rz+LimitedVariableRenameVisitor.record_skipped2s RT"r4c|jj}|jj}d|vrP|jD]<\}}t |dks||vr|dd}t |D]\}}t ||>yy)Nrr r)r-rrrrrr)r1ref_dictrrDr-rrrs r2rz'LimitedVariableRenameVisitor.flush_refs5s99==?,,""$ g &nn. ) dt9>TW_!"I (3)GAta()  ) r4rrrrr)rrrrrr)r}rrrrrr)rrrrr3r?rLrPrxr]rrrrrr8rArrrrs@r2rrs]: >)* "-.- - 4& !# )r4rcT|dj}|d|dzzz}|D] }||_ y)Nr'r )rD)rr^rDnew_namer\s r2rrCs8 8==DcUQY''H r4N)rzlist[NameExpr]r^rrr)* __future__rcollections.abcr contextlibrtypingr mypy.nodesrrr r r r r rrrrrrrrrrrrrrr mypy.patternsrmypy.traverserrr__annotations__r!r#r%rrr4r2rs{"$%0$+e%u@,@F U)#3U)pr4