
    +j'                         d 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 ddlmZ eegZn# e$ r g ZY nw xY wg dZdZdZd Zdd	Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdZ dS )a  Automatically reload function code each time it is called

This module provides a `hot_reload` decorator where the decorated function
is reloaded from source every time the function is called. This works
primarily for global functions and class methods, but it also has
limited support for nested functions as well*.

This module also provides a `reload` function that can be used to reload
a function on demand, i. e. `new_func = reload(old_func)`.

This module is based upon Julian Vossen's reloading library:
https://github.com/julvo/reloading

But it is heavily modified, and includes additional support for things
like class methods. The license for the original library is pasted at
the bottom of this file.

* Nested functions have the following issues:

1. You cannot use the `nonlocal` statement in nested functions. When
the code is reloaded, Python treats it as a global function, and
therefore the `nonlocal` keyword is not allowed.
2. You cannot add capture variables during reloading. Whatever was
captured when the function was first defined is what will continue
to be captured. This is because the outer function is never reloaded,
and the outer function's local scope may potentially be gone at the
time of decorating.
3. If some of the capture variables share the same name as global
variables, but are different, then references to the global variable
within the function or functions it calls may end up referring to
the capture variable instead.
    N)Path)AbstractLayout)AbstractElement)ctrlstate
life_cycleTc                 z     t           dd          r S t          j                    fd            }d|_        |S )zDecorator to reload the function on every call

    If there are multiple decorators on this function, only the
    decorators after the `@hot_reload` decorator will be reloaded
    __is_hot_reload_funcFc                  6    t          d          } || i |S )NF)perform_checks)reload)argskwargsnew_funcfuncs      W/DATA/AppData/hermes/venv/lib/python3.11/site-packages/trame_server/utils/hot_reload.pywrappedzhot_reload.<locals>.wrappedN   s,     $u555x((((    T)getattr	functoolswrapsr
   )r   r   s   ` r   
hot_reloadr   C   s^     t+U33  _T) ) ) ) ) $(G Nr   c                    |rt          | t          j        t          j        f          s| S t          | t          j                  r)t          | j        t          t                              r| S t          rd| j        v r| S t          rt          |           r| S 	 	 t          |           S # t          $ r t          |            Y nw xY w0)aD  Attempt to reload the provided function

    This works by locating the file the function was defined in, reloading its
    body of code, and returning the reloaded function.

    If perform_checks is True, then several checks will be performed beforehand
    to determine whether or not the function should be skipped.
    z<lambda>)
isinstancetypesFunctionType
MethodType__self__tupleSKIP_CLASSESSKIP_LAMBDA_FUNCS__qualname__SKIP_SITE_PACKAGES_func_in_site_packages_reload_func	Exception_handle_exception)r   r   s     r   r   r   Z   s      $!3U5E FGG 	KdE,-- 	$-|)<)<==  	t/@!@!@K 	"8">"> 	K$	$%%% 	$ 	$ 	$d#####	$$s   B) )CCc                 @   t          |           }t          |           }| j                                        }|                    |           t          ||           || j                 }t          | t          j	                  rt          j	        || j
                  }|S N)_find_function_locals_recompile_function__globals__copyupdateexec__name__r   r   r   r   )r   func_localscodeglobals_copyr   s        r   r%   r%   |   s    '--Kt$$D  #((**L$$$|DM*H$()) =#Hdm<<Or   c                 T    d| j         vr| j        S t          j        |           j        S )Nz<locals>)r"   r,   inspectgetclosurevars	nonlocals)r   s    r   r*   r*      s1     *** !$''11r   c                     t          |           }t          | j        |          s1t          j        |           }d| j         d| d}t          |          t          |dd          S )NzFailed to find 'z' in file '' r/   )filenamemode)!_parse_func_file_until_successful_isolate_function_defr0   r5   getfiler"   r&   compile)r   treepathmsgs       r   r+   r+      sn    ,T22D 55 t$$F!2FFtFFFnn4"62222r   c                     t          j        |           }	 t          |          }	 t          j        |          S # t
          $ r t          |            Y nw xY wDr)   )r5   r?   
_load_fileastparseSyntaxErrorr'   )r   rB   sources      r   r=   r=      sl    ?4  D$D!!	$9V$$$ 	$ 	$ 	$d#####	$	$s   : AAc                 j    d}|dk    r't          |                                           }|dk    '|dz   S )Nr:   
)r   	read_text)rB   srcs     r   rE   rE      s<    
C
))4jj""$$ )):r   c                    t          j        |          D ]k}t          |t           j                  rO|j        | k    rDd |j        D             }d|v rt          |           t          |t                     |g|_	         dS ldS )zStrip everything but the function definition from the ast in-place.
    Also strips the hot_reload decorator (including all decorators before it)
    from the function definitionc                 ,    g | ]}t          |          S  _get_decorator_name.0decs     r   
<listcomp>z)_isolate_function_def.<locals>.<listcomp>   s!    WWWC2377WWWr   r   TF)
rF   walkr   FunctionDefnamedecorator_list_strip_hot_reload_decorator_strip_decoratorsSTRIP_DECORATORSbody)funcnamerA   nodedecorator_namess       r   r>   r>      s      
 
dCO,, 		h1F1FWW4CVWWWO..+D111 d$4555DI445r   c                 >   t          j        |           }t          j                    }|                    dd| d          }t
          j                            |dz              t          d| j	         d| d           t
          j
                                         d S )NzFile "<string>"zFile ""rK   zEdit 'z' in 'z' and press return to continue)r5   r?   	traceback
format_excreplacesysstderrwriteprintr"   stdinreadline)r   fpathexcs      r   r'   r'      s    OD!!E


 
 C
++'):%):):):
;
;CJS4Z   	
Q4$
Q
QE
Q
Q
QRRRIr   c                 >   t          | d          r| j        S t          | d          rGt          | j        d          r| j        j        S t          | j        d          r| j        j        j        S t          | d          r| j        j        S d|  }t	          |          )Nidr   valuezFailed to find decorator name: )hasattrrp   r   rq   r&   )dec_noderC   s     r   rR   rR      s    x {x   *8=$'' 	$=##8='** 	*=&))x!! !~  
6H
6
6C
C..r   c                     d | j         D             }|                    d          }| j         |dz   d         | _         dS )z>Remove the 'hot_reload' decorator and all decorators before itc                 ,    g | ]}t          |          S rP   rQ   rS   s     r   rV   z/_strip_hot_reload_decorator.<locals>.<listcomp>   s!    OOOC*3//OOOr   r      N)rZ   index)r   ra   hot_reload_idxs      r   r[   r[      sL    OO4;NOOOO$**<88N-nq.@.B.BCDr   c                 8    fd| j         D             | _         dS )zStrip only specific decoratorsc                 6    g | ]}t          |          v|S rP   rQ   )rT   rU   	blacklists     r   rV   z%_strip_decorators.<locals>.<listcomp>   s3       .A#.F.Fi.W.W.W.W.Wr   N)rZ   )r   r{   s    `r   r\   r\      s7       *  Dr   c                     t          j        |           t          fdt          j                    D                       S )z=Return whether a function is in any site-packages directoriesc              3   B   K   | ]}                     |          V  d S r)   )
startswith)rT   xrB   s     r   	<genexpr>z)_func_in_site_packages.<locals>.<genexpr>  s/      BBatq!!BBBBBBr   )r5   r?   anysitegetsitepackages)r   rB   s    @r   r$   r$      s>    ?4  DBBBB4+?+A+ABBBBBBr   a*  MIT License
Copyright (c) 2019 Julian Vossen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
)T)!__doc__rF   r   r5   r   rg   rd   r   pathlibr   trame_client.ui.corer   trame_client.widgets.corer   r    ImportErrorr]   r!   r#   r   r   r%   r*   r+   r=   rE   r>   r'   rR   r[   r\   r$   JULVO_RELOADING_LICENSErP   r   r   <module>r      s   B 


       



           333333999999 $^4LL   LLL
 322       .$ $ $ $D  >2 2 23 3 3$ $ $    &    "D D D  C C C   s   7 A A