
    Xhb                       d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlmZ d dlmZmZmZmZmZmZ d dlmZ erMej,                  ej.                  z  ej0                  z  ej2                  z  ej4                  z  ej6                  z  ZddZddZ G d d	e      Z G d
 de      Z  G d dejB                        Z" G d d      Z# G d de      Z$y)    )annotationsN)
ModuleType)TYPE_CHECKINGAny	GeneratorIterable
NamedTuplecast)DeduperReloaderPatchingMixinc                    t        | t              rt        j                  j	                  |       n| x}yt        |dd      xs dS )zHReturns the module's file path, or the empty string if it's inaccessible __file__)
isinstancestrsysmodulesgetgetattr)modulemods     b/var/www/html/myenv/lib/python3.12/site-packages/IPython/extensions/deduperreload/deduperreload.pyget_module_file_namer      s<    *4VS*As{{v&vMV3
B'-2-    c                   t        |       t        |      uryt        | t        j                        rL| j                  j                         D ].  \  }}|dv rt        ||      rt        |t        ||            r. y yt        | t              rEt        |t              r5t        |       t        |      k(  xr t        d t        | |      D              S | |k(  S )zYChecks if node1 and node2 have identical AST structure/values, apart from some attributesF)lineno
end_lineno
col_offsetend_col_offsetctxparentTc              3  :   K   | ]  \  }}t        ||        y wN)compare_ast).0n1n2s      r   	<genexpr>zcompare_ast.<locals>.<genexpr>;   s       0
$*BKB0
s   )typer   astAST__dict__itemshasattrr#   r   listlenallzip)node1node2kvs       r   r#   r#   $   s    E{$u+%%!NN((* 	DAq   5!$K75!;L,M	 	E4	 Zt& 5zSZ' 
C 0
.1%.?0
 -
 	
 ~r   c                  &    e Zd ZU dZded<   ded<   y)DependencyNodea  
    Each node represents a function.
    qualified_name: string which represents the namespace/name of the function
    abstract_syntax_tree: subtree of the overall module which corresponds to this function

    qualified_name is of the structure: (namespace1, namespace2, ..., name)

    For example, foo() in the following would be represented as (A, B, foo):

    class A:
        class B:
            def foo():
                pass
    tuple[str, ...]qualified_nameast.ASTabstract_syntax_treeN)__name__
__module____qualname____doc____annotations__ r   r   r7   r7   B   s     $#!!r   r7   c                  v    e Zd ZU g Zded<   g Zded<   g Zded<   i Zded<   g Zd	ed
<   e	dd       Z
ddZddZy)GatherResultz9list[tuple[tuple[str, ...], ast.Import | ast.ImportFrom]]import_defsz8list[tuple[tuple[str, ...], ast.Assign | ast.AnnAssign]]assign_defszDlist[tuple[tuple[str, ...], ast.FunctionDef | ast.AsyncFunctionDef]]function_defszdict[str, ast.ClassDef]classeszlist[ast.AST]	unfixablec                     | g g g i g       S r"   rA   )clss    r   createzGatherResult.create_   s    2r2r2&&r   c                l    t        j                  | j                  | j                  | j                        S r"   )	itertoolschainrD   rE   rF   selfs    r   all_defszGatherResult.all_defsc   s'    t//1A1A4CUCUVVr   c                v   | j                   j                  |j                          | j                  j                  |j                         | j                  j                  |j                         | j                  j                  |j                         | j                  j                  |j                         y r"   )rD   extendrE   rF   rG   updaterH   )rP   others     r   inplace_mergezGatherResult.inplace_mergef   s|     1 12 1 12!!%"5"56EMM*eoo.r   N)returnrC   )rW   z0Iterable[tuple[tuple[str, ...], TDefinitionAst]])rU   rC   rW   None)r<   r=   r>   rD   r@   rE   rF   rG   rH   classmethodrK   rQ   rV   rA   r   r   rC   rC   V   s`    MOKJOLNKIN 	    (*G$)!I}!' 'W/r   rC   c                  f     e Zd ZddZej
                  dd       Zd	dZd
dZd fdZ	ddZ
 xZS )ConstexprDetectorc                     d| _         d| _        y NT)is_constexpr_allow_builtins_exceptionsrO   s    r   __init__zConstexprDetector.__init__o   s     *.'r   c              #  b   K   | j                   }d| _         	 d  || _         y # || _         w xY wwNF)r_   )rP   
prev_allows     r   disallow_builtins_exceptionsz.ConstexprDetector.disallow_builtins_exceptionss   s1     44
*/'	9.8D+jD+s   /# /	,/c                    | j                         5  | j                  |j                         d d d        y # 1 sw Y   y xY wr"   )rd   visitvaluerP   nodes     r   visit_Attributez!ConstexprDetector.visit_Attribute|   s3    ..0 	#JJtzz"	# 	# 	#s   6?c                `    | j                   rt        t        |j                        ry d| _        y rb   )r_   r-   builtinsidr^   rh   s     r   
visit_NamezConstexprDetector.visit_Name   s#    **wx/I!r   c                >    | j                   sy t        | 	  |       y r"   )r^   superrf   )rP   ri   	__class__s     r   rf   zConstexprDetector.visit   s      dr   c                J    d| _         | j                  |       | j                   S r]   )r^   rf   rh   s     r   __call__zConstexprDetector.__call__   s"     

4   r   rW   rX   )rW   zGenerator[None, None, None])ri   zast.AttributerW   rX   )ri   zast.NamerW   rX   )ri   r:   rW   rX   )ri   r:   rW   bool)r<   r=   r>   r`   
contextlibcontextmanagerrd   rj   rn   rf   rs   __classcell__)rq   s   @r   r[   r[   n   s6    / 9 9#"
!r   r[   c                       e Zd ZdZddZddZy)AutoreloadTreea  
    Recursive data structure to keep track of reloadable functions/methods. Each object corresponds to a specific scope level.
    children: classes inside given scope, maps class name to autoreload tree for that class's scope
    funcs_to_autoreload: list of function names that can be autoreloaded in given scope.
    new_nested_classes: Classes getting added in new autoreload cycle
    c                L    i | _         g | _        t               | _        i | _        y r"   )childrendefs_to_reloadsetdefs_to_deletenew_nested_classesrO   s    r   r`   zAutoreloadTree.__init__   s#    35EG(+68r   c                    | }|D ]6  }||j                   vrt               |j                   |<   |j                   |   }8 |S )zY
        Return ref to the AutoreloadTree at the namespace specified by prefixes
        )r|   rz   )rP   prefixescurprefixs       r   traverse_prefixesz AutoreloadTree.traverse_prefixes   sJ      	'FS\\)'5'7V$,,v&C	' 
r   Nrt   )r   z	list[str]rW   rz   )r<   r=   r>   r?   r`   r   rA   r   r   rz   rz      s    9	r   rz   c                  ^   e Zd ZdZddZedd       Zej                  dd       ZddZ e	       Z
edd       Ze	 	 	 	 	 	 dd       Ze	 	 	 	 	 	 dd       Z	 d	 	 	 	 	 	 	 dd
ZddZddZ	 d	 	 	 ddZddZ	 d	 	 	 	 	 d dZ	 d	 	 	 	 	 d dZd!dZ	 	 	 	 	 	 d"dZ	 d	 	 	 	 	 d#dZd$dZy	)%DeduperReloadera  
    This version of autoreload detects when we can leverage targeted recompilation of a subset of a module and patching
    existing function/method objects to reflect these changes.

    Detects what functions/methods can be reloaded by recursively comparing the old/new AST of module-level classes,
    module-level classes' methods, recursing through nested classes' methods. If other changes are made, original
    autoreload algorithm is called directly.
    c                L    t               | _        i | _        i | _        d| _        y r]   )rz   _to_autoreloadsource_by_modnamedependency_graph_enabledrO   s    r   r`   zDeduperReloader.__init__   s$    .<.>13MOr   c                L    | j                   xr t        j                         dk(  S )NCPython)r   platformpython_implementationrO   s    r   enabledzDeduperReloader.enabled   s    }}N!?!?!AY!NNr   c                    || _         y r"   )r   )rP   rg   s     r   r   zDeduperReloader.enabled   s	    r   c                   | j                   syt        j                  j                         | j                  j                         z
  D ]  }t        j                  |   }t        |      x},d|v s(d|v s$t        j                  |t        j                        sd| j                  |<   _t        |d      5 }	 |j                         | j                  |<   ddd        y# t        $ r d| j                  |<   Y %w xY w# 1 sw Y   xY w)zY
        Update dictionary source_by_modname with current modules' source codes.
        Nzsite-packageszdist-packagesr   r)r   r   r   keysr   r   osaccessR_OKopenread	Exception)rP   new_modname
new_modulefnamefs        r   update_sourceszDeduperReloader.update_sources   s     ||;;++-0F0F0K0K0MM 	=K[1J.z::C"e+"e+yy068&&{3eS! =Q=:;&&(D**;7= =	= ! =:<D**;7== =s*   2C:4CC74C:6C77C::D	c                   t        | t        j                        ry| j                  D ]  }t        |t        j                        r|j
                  dk(  r yt        |t        j                        sI|j                  dk(  sYt        |j                  t        j                        s~|j                  j
                  dk(  s y y)NFEnumTenum)	r   r)   ModulebasesNamerm   	Attributeattrrg   )ri   bases     r   is_enum_subclassz DeduperReloader.is_enum_subclass   s    dCJJ'JJ 		D$)dgg.?4/II'tzz3884JJMMV+		 r   c                r   t        |t        j                  t        j                  f      r|j                  y| j                  |      ryt        |t        j                        r|j                  n|j                  gD ]  }t        |t        j                        r y | j                  |j                        S rb   )
r   r)   Assign	AnnAssignrg   r   targetstargetr   constexpr_detector)rJ   ri   parent_noder   s       r   is_constexpr_assignz#DeduperReloader.is_constexpr_assign   s     $S]] ;<

@R,&0szz&Bdll 	Ffchh/	 %%djj11r   c                   t         j                         }|D ]4  }|}t        |t        j                        r'|j
                  }t        |t        j                        r't        |t        j                  t        j                  f      r)|j                  j                  |j                  f|f       t        |t        j                  t        j                  f      r8|j                  j                  t        d |j                  D              |f       t        |t        j                         r||j"                  |j                  <   1t        |t        j$                        r}|j&                  j                  |j(                         |j+                  | j-                  |j.                  |             |j+                  | j-                  |j0                  |             t        |t        j2                  t        j4                  f      rR|j&                  j7                  |j8                         |j+                  | j-                  |j.                  |             Dt        |t        j:                        r|j+                  | j-                  |j.                  |             |j+                  | j-                  |j0                  |             |j+                  | j-                  |j<                  |             |j>                  D ]^  }|j@                  %|j&                  j                  |j@                         |j+                  | j-                  |j.                  |             ` Nt        |t        jB                  t        jD                  f      rz| jG                  ||      rt        |t        jH                  t        jJ                  f      sJ t        |t        jH                        r|jL                  n|jN                  g}|jP                  j                  t        d |D              |f       |j&                  j                  |       7 |S )z
        Given list of ast elements, return:
        1. dict mapping function names to their ASTs.
        2. dict mapping class names to their ASTs.
        3. list of any other ASTs.
        c              3  P   K   | ]  }|j                   xs |j                     y wr"   )asnamename)r$   r   s     r   r'   z3DeduperReloader._gather_children.<locals>.<genexpr>  s      N4;;3$))3Ns   $&c              3  d   K   | ](  }t        t        j                  |      j                   * y wr"   )r
   r)   r   rm   )r$   r   s     r   r'   z3DeduperReloader._gather_children.<locals>.<genexpr>,  s!     !R$sxx"8";";!Rs   .0))rC   rK   r   r)   Exprrg   FunctionDefAsyncFunctionDefrF   appendr   Import
ImportFromrD   tuplenamesClassDefrG   IfrH   testrV   _gather_childrenbodyorelse	AsyncWithWithrS   r,   Try	finalbodyhandlersr(   ConstantPassr   r   r   r   r   rE   )rJ   r   r   resultast_nodeast_elthandlerr   s           r   r   z DeduperReloader._gather_children   s     $$& .	5H+3GWchh/!-- Wchh/'COOS5I5I#JK$$++gll_g,FGGcjj#..%AB""))NNNPWX GS\\2/6w||,GSVV,  ''5$$S%9%9',,%TU$$S%9%9'..+%VWGcmmSXX%>?  ''6$$S%9%9',,%TUGSWW-$$S%9%9',,%TU$$S%9%9'..+%VW$$(():):KH  '// G||/((//=((,,W\\;G  #,,)AB**7K@%g

CMM/JKKK &gszz:  %nn- 
 &&--!!R'!RR# $$++G4].	5^ r   Nc                X   | j                   sy|xs g }| j                  |j                  |      }| j                  |j                  |      }|j                         D ci c]  \  }}|D ]  }||  }	}}}|j                         D ci c]  \  }}|D ]  }||  }
}}}t	        |j
                  |j
                        sy| j                  j                  |      }|j                         D ]d  \  }}g }|D ]/  }|
|   |ur||	vst	        ||	|         r|j                  |       1 |s?|j                  j                  t        |      |f       f |xj                  t        |	j                               t        |
j                               z
  z  c_        |j                  j                         D ]c  \  }}||j                  vr||j                   |<   $t	        ||j                  |         r>| j#                  |j                  |   |||gz         rc y yc c}}}w c c}}}w )z
        Returns
        -------
        `True` if we can run our targeted autoreload algorithm safely.
        `False` if we should instead use IPython's original autoreload implementation.
        FT)r   r   r   rQ   r#   rH   r   r   r   r}   r   r   r~   r   rG   r,   r   detect_autoreload)rP   old_nodenew_noder   
old_result
new_resultr   ast_defr   old_defs_by_namenew_defs_by_namer   new_ast_defnames_to_reloadnew_ast_def_classs                  r   r   z!DeduperReloader.detect_autoreload4  sc    ||>r**8==(C
**8==(C
0:0C0C0E0
 0
,eWRW0
JND'M0
0
 0
 1;0C0C0E0
 0
,eWRW0
JND'M0
0
 0
 ://1E1EF!!33H=","5"5"7 
	GE; O 1#D)<//{!1$!78 $**401 ""))5<*EF
	G 	c"2"7"7"9:S!!#>
 
 	
 (2'9'9'?'?'A 	#D#:---/@&&t, !:#5#5d#;,,""4(*;X=N 	 E0
0
s    HH%c                P    | j                         D ]  }| j                  |        y)z
        If a decorator function is modified, we should similarly reload the functions which are decorated by this
        decorator. Iterate through the Dependency Graph to find such cases in the given AutoreloadTree.
        T)_check_dependents_inner_add_node_to_autoreload_treerh   s     r   _check_dependentsz!DeduperReloader._check_dependentsj  s-    
 002 	4D--d3	4r   c                   t        |j                        dk(  ry| j                  j                  t	        |j                  dd             }|j
                  6|j                  j                  |j                  d   f|j
                  f       yy)zj
        Given a node of the dependency graph, add decorator dependencies to the autoreload tree.
        r   N)r/   r9   r   r   r.   r;   r}   r   )rP   ri   r   s      r   r   z,DeduperReloader._add_node_to_autoreload_trees  s     t""#q(!!33D9L9LSb9Q4RS$$0%%%%b)+T-F-FG 1r   c                @   |xs g }| j                   j                  |      }g }|j                  D ]6  \  ^}}}t        ||gz         }|j	                  | j                  |             8 |j                  D ]&  }|j	                  | j                  ||gz                ( |S r"   )r   r   r}   r   rS   _gen_dependentsr   r   )rP   r   r   ans	func_name_ri   
class_names           r   r   z'DeduperReloader._check_dependents_inner  s     >r!!33H="%"4"4 	3OYQYK/0DJJt++D12	3 00 	NJJJt33H
|4KLM	N
r   c                    g }|| j                   vrg S | j                   |   D ]=  }|j                  | j                  |j                               |j	                  |       ? |S r"   )r   rS   r   r9   r   )rP   qualnamer   elts       r   r   zDeduperReloader._gen_dependents  sc    4000I((2 	CJJt++C,>,>?@JJsO	 
r   c           
     
   |xs g }| j                   j                  |      }|}|D ]  }|j                  |   } t               }|j                  D ]v  \  }}t        |      dk(  r|d   |v r|j                  |       i }	t        |t        j                  t        j                  f      r|d   x}
|j                  v rt        |      dk(  sJ |j                  |
   }t        |t        t        f      r|j                  }t        j                  t        j                   |            }t        |      dkD  x}rdt        j"                  |d      z   }|j                  }t        |t$              st%        |      }t'        |dd      xr |j(                  j*                  xs d}t        j,                  |      g}t        t/        t        j                  |d   j0                  d         j2                        dkD  rit5        j6                  t5        j8                  |d               }g t/        t        j                  |j0                  d         _        |j;                  d|       |D ]  }t=        ||dd	
      }t?        |||	       |rt'        |	d   |
      }n|	|
   }t        |t        t        f      r|j                  }t        |t@              rkt        |t@              r[dD ]U  }t'        ||      t'        ||      | jC                  |||       /| jE                  t'        ||      t'        ||      |       W t        |t@              s%t        |t@              s| jE                  |||       	tG        d       )t?        t        j                   |      |j                  |j                  z  |	       |D ]  }
tI        ||
|	|
           y |j                  jK                          |jL                  D ]  }
	 tO        ||
        |jL                  jK                          |jT                  jW                         D ]N  \  }}i }t?        t        j                   |      |j                  |j                  z  |       tI        ||||          P |jT                  jK                          |jX                  j[                         D ]  }| j]                  |||gz         r y |jX                  jK                          y	# tP        tR        tF        f$ r Y w xY w)a  
        This function patches module functions and methods. Specifically, only objects with their name in
        self.to_autoreload will be considered for patching. If an object has been marked to be autoreloaded,
        new_source_code gets executed in the old version's global environment. Then, replace the old function's
        attributes with the new function's attributes.
           r   zclass __autoreload_class__:
z    __code__Nz<string>execT)modedont_inherit__autoreload_class__)fgetfsetfdelz5adding or removing property decorations not supportedF)/r   r   r+   r~   r}   r/   rT   r   r)   r   r   staticmethodrY   __func__textwrapdedentunparseindentdictr   r   co_filenameparser
   r   decorator_listpickleloadsdumpsinsertcompiler   propertytry_patch_attrpatch_function
ValueErrorsetattrclearr   delattrAttributeError	TypeErrorr   r,   r|   r   _patch_namespace)rP   nsr   r   namespace_to_checkr   
seen_namesr   r   	local_envr   to_patch_to	func_code	is_method
global_envfilename	func_astswithout_decorator_listfunc_astcompiled_codeto_patch_fromr   r   class_ast_nodelocal_env_classs                            r   _patch_namespace_innerz&DeduperReloader._patch_namespace_inner  s    >r!!33H= 	EF!3!<!<V!D	E"u
"%"4"4 M	GE;5zQ58z#9e$(*I;#:N:N(OP"1X%T*<*E*EE5zQ&099$?kL++FG"-"6"6K$OOCKK,DE	!$X!2393 ?(//!6C !I  [[
!*d3!%j!1J KT: 9#,,88"! 
 !YYy12	tCOOYq\->->q-ABQQRUVV-3\\&,,yQR|:T-U* (* )?)D)DQ)G$$$Q(>? ) "H$+ (d%M 
I> (/	:P0QSW(X(1$!-,1LM(5(>(>!+x8Z%x> %= "D 'T : B#*=$#?#G $ 3 3KPT U $ 3 3$+K$>$+M4$@$-!"" (X>z%xH ++K	R(S A"H KK,KK"4"="==
 " GD.ioFGYM	G\ 	  "&& 	D*D1	 	  "*-*@*@*F*F*H 	Q&J.0ON+0999
 &
OJ4OP	Q 	$$&,,++- 	J((X-DE	 	# #Iz: s   4S33T
Tc                H    	 | j                  ||      S # t        $ r Y yw xY w)z
        Wrapper for patching all elements in a namespace as specified by the to_autoreload member variable.
        Returns `true` if patching was successful, and `false` if unsuccessful.
        )r   F)r  r   )rP   r  r   s      r   r  z DeduperReloader._patch_namespace	  s/    	..rH.EE 		s    	!!c                   | j                   syt        |dd      x}syt        |      x}yt        |d      5 }|j	                         }ddd       d}| j
                  j                  |      x}r	 t        j                  |      }t        j                        }	t        j                         }
|
5  | j                  |	       | j                  ||	      r#| j                         r| j                  |      rd}ddd       | j
                  |<   t!               | _        |S # 1 sw Y   xY w# t        $ r Y yw xY w# 1 sw Y   DxY w)zy
        Uses Deduperreload to try to update a module.
        Returns `true` on success and `false` on failure.
        Fr<   Nr   T)r   r   r   r   r   r   r   r)   r   r   rv   suppress_build_dependency_graphr   r   r  rz   r   )rP   r   modnamer   r   new_source_codepatched_flagold_source_codeold_module_astnew_module_astr   s              r   maybe_reload_modulez#DeduperReloader.maybe_reload_module  sA   
 ||"6:t<<<)&11E:% 	'ffhO	'"4488AA?A!$?!;!$?!; %%'C (,,^<**>>J..0--f5#'L( +:w',./	' 	'  ( (s*   D 1*D, 1AD; D),	D87D8;Ec                V   t        |t        j                        r|j                  gS t        |t        j                        r|r| j                  |j                  d      S yt        |t        j                        sy| j                  |j                  d      x}r||j                  gz   S y)ze
        Generates a qualified name for a given decorator by finding its relative namespace.
        FN)
r   r)   r   rm   Call_separate_namefuncr   rg   r   )rP   	decoratoraccept_callsprefs       r   r-  zDeduperReloader._separate_name9  s     i*LL>!	388,**9>>5AA)S]]3&&y>>4>9>>***r   c                   |xs g }|D ]  }|}t        |t        j                        r+| j                  |j                  ||j
                  gz          Jt        |t        j                  t        j                  f      sut        ||j
                  gz         }t        ||      }|j                  D ]M  }| j                  |d      }|st        |      }	| j                  j                  |	g       j                  |       O  yr]   )r   r)   r   _gather_dependentsr   r   r   r   r   r7   r   r-  r   
setdefaultr   )
rP   r   body_prefixesr   r   r9   cur_dependency_noder/  decorator_pathdecorator_path_tuples
             r   r3  z"DeduperReloader._gather_dependentsO  s     &+ 	H+3G'3<<0''mw||n6TUg9M9M'NO"=GLL>#ABN"0"I$33 	!%!4!4Y!E%',^'<$%%001ErJQQ'	" r   c                8    | j                  |j                        S )z
        Wrapper function for generating dependency graph given some AST.
        Returns `true` on success. Returns `false` on failure.
        Currently, only returns `true` as we do not block on failure to build this graph.
        )r3  r   )rP   new_asts     r   r#  z'DeduperReloader._build_dependency_graphf  s     &&w||44r   rt   )rW   ru   )rg   ru   rW   rX   )ri   ast.Module | ast.ClassDefrW   ru   )ri   r:   r   r;  rW   ru   )r   list[ast.stmt]r   r;  rW   rC   r"   )r   r;  r   r;  r   list[str] | NonerW   ru   )ri   r7   rW   rX   )r   r=  rW   list[DependencyNode])r   r8   rW   r>  )r  zModuleType | typer   r=  rW   ru   )r   r   rW   ru   )r/  z.ast.Attribute | ast.Name | ast.Call | ast.exprr0  ru   rW   r=  )r   r<  r5  r=  rW   ru   )r:  r;  rW   ru   )r<   r=   r>   r?   r`   r  r   setterr   r[   r   r   r   rY   r   r   r   r   r   r   r   r  r  r*  r-  r3  r#  rA   r   r   r   r      s    O O ^^ =, +,  
2
2)B
2	
2 
2 9!90I9	9 9~ &*	4+4 ,4 #	4
 
4l
 ,0(	 CGr#r/?r	rj CG
#
/?
	
"HA  
	. GK"3C	.5r   r   )r   zModuleType | strrW   z
str | None)r2   ast.AST | list[ast.AST]r3   r@  rW   ru   )%
__future__r   r)   rl   rv   rM   r   r   r   r   r   typesr   typingr   r   r   r   r	   r
   7IPython.extensions.deduperreload.deduperreload_patchingr   r   r   r   r   r   r   TDefinitionAstr   r#   r7   rC   NodeVisitorr[   rz   r   rA   r   r   <module>rG     s    " 
    	   
   L L 


	
**	 ..	 **		
 --	 .<"Z "(/: /0 !  !F 4A52 A5r   