a
    ij                     @  sd  d Z 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mZ ddlZddlmZ ddlmZ G dd dejZejd	d
ddZejddG dd dZG dd	 d	ZddddddZddddddZdddddd Zd!d" Zd#d$ Zd%d& Z d'd( Z!d)d* Z"e#efej$e fej%d+d, fe&e!fgZ'd-d. Z(dS )/zHot reload.    )annotationsN)AnyIterator)epy)module_utilsc                   @  s(   e Zd ZdZe Ze Ze ZdS )
ReloadModea^  Invalidate mode.

  When reloading a module, indicate what to do with the old module instance.

  Attributes:
    UPDATE_INPLACE: Update the old module instances with the new reloaded values
    INVALIDATE: Clear the old module so it cannot be reused.
    KEEP_OLD: Do not do anything, so 2 versions of the module coohexist at the
      same time.
  N)	__name__
__module____qualname____doc__enumautoUPDATE_INPLACE
INVALIDATEZKEEP_OLD r   r   Y/home/ghrups/robot-bench/.venv/lib/python3.9/site-packages/etils/ecolab/inplace_reload.pyr   #   s   
r   _InPlaceReloader)returnc                   C  s   t  S )z(Returns the singleton in-place reloader.)r   r   r   r   r   get_reloader3   s    r   T)frozenc                   @  s^   e Zd ZU dZejedZded< ejdd dZ	ded< d	d
dddZ
d	d
dddZdS )_ModuleRefsz2Reference on the previous module/object instances.)default_factoryz#list[weakref.ref[types.ModuleType]]modulesc                   C  s
   t tS N)collectionsdefaultdictlistr   r   r   r   <lambda>A       z_ModuleRefs.<lambda>z!dict[str, list[weakref.ref[Any]]]objstypes.ModuleTypeNone)moduler   c                 C  sL   | j t| |j D ]*\}}t||s0q| j| t| qdS )z/Save reference on all previous modules/objects.N)r   appendweakrefref__dict__items_belong_to_moduler   )selfr"   nameold_objr   r   r   save_moduleD   s
    
z_ModuleRefs.save_module)
new_moduler   c                 C  sx   | j D ]}| }|du rqt|| q| j D ]B\}}||jvrDq0|j| }|D ]}| }|du rfqRt|| qRq0dS )z-Update all old reference to previous objects.N)r   _update_old_moduler   r'   r&   _update_generic)r)   r-   
old_moduler*   Zold_obj_refsnew_objZold_obj_refr+   r   r   r   update_refs_with_new_moduleO   s    


z'_ModuleRefs.update_refs_with_new_moduleN)r   r	   r
   r   dataclassesfieldr   r   __annotations__r   r,   r2   r   r   r   r   r   9   s   
r   c                   @  sB   e Zd ZdZdd Zejdddddd	d
ZdddddZdS )r   z0Global manager which track all reloaded modules.c                 C  s   t t| _d S r   )r   r   r   _previous_modules)r)   r   r   r   __init__k   s    z_InPlaceReloader.__init__	list[str]boolr   zIterator[None])reloadverbosereload_moder   c             
   c  sl   | j |d tj|||tjkr"dndd z"dV  W |tjkrht|| jd n|tjkrft|| jd 0 dS )zEventually update old modules.)r:   TF)r   r;   Z
invalidateN)r:   previous_modules)
_save_objsr   Zclear_cached_modulesr   r   r   _update_old_modulesr6   )r)   r:   r;   r<   r   r   r   update_old_moduless   s$    

z#_InPlaceReloader.update_old_modulesr!   )r:   r   c                C  s:   t |D ]*}tj|}|du r$q
| j| | q
dS )zSave all modules/objects.N)r   get_module_namessysr   getr6   r,   )r)   r:   module_namer"   r   r   r   r>      s
    z_InPlaceReloader._save_objsN)	r   r	   r
   r   r7   
contextlibcontextmanagerr@   r>   r   r   r   r   r   h   s
   !r8   zdict[str, _ModuleRefs]r!   )r:   r=   r   c                 C  s:   t | D ]*}tj| }||}|dur
|| q
dS )zUpdate all old modules.N)r   rA   rB   r   rC   r2   )r:   r=   rD   r-   Zold_module_refsr   r   r   r?      s
    

r?   r    )r0   r-   r   c                 C  s   | j   | j |j  dS )zMutate the old module version with the new dict.

  This also try to update the class, functions,... from the old module (so
  instances are updated in-place).

  Args:
    old_module: Old module to update
    new_module: New module
  N)r&   clearupdate)r0   r-   r   r   r   r.      s    
r.   r   r9   )objr"   r   c                 C  s   t | do| j|jkS )zAReturns `True` if the instance, class, function belong to module.r	   )hasattrr	   r   )rI   r"   r   r   r   r(      s    r(   c                   s&   t t fdd}|S )Nc                    s    g| R i |S r   r   )argskwargsnew_fnold_fnr   r   	decorated   s    z_wrap_fn.<locals>.decorated)inspectunwrap	functoolswraps)rO   rN   rP   r   rM   r   _wrap_fn   s    
rU   c                 C  s   t | j D ]}t| |}zt||}W n< tyf   zt| | W n ttfy\   Y n0 Y qY n0 t|| zt| |t|| W q ttfy   Y q0 qt	| | dS )zUpdate the class.N)
r   r&   keysgetattrAttributeErrordelattr	TypeErrorr/   setattr_update_instances)oldnewkeyr+   r1   r   r   r   _update_class   s     


r`   c              
   C  s<   dD ]2}zt | |t|| W q ttfy4   Y q0 qdS )z&Upgrade the code object of a function.)__code____defaults__r   __closure____globals__r&   N)r[   rW   rX   rZ   )r]   r^   r*   r   r   r   _update_function   s
    re   c                 C  s.   t | j|j t | j|j t | j|j dS )z,Replace get/set/del functions of a property.N)r/   fdelfgetfset)r]   r^   r   r   r   _update_property   s    ri   c                 C  sB   | |u rd S t D ],\}}t| |rt||r|| |  dS qd S )NT)_UPDATE_RULES
isinstance)r]   r^   type_rH   r   r   r   r/     s    
r/   c                 C  s   t | j|jS r   )re   __func__)abr   r   r   r     r   r   c                 C  s2   t | }|D ]}t|| u rt|d| qdS )zBackport of `update_instances`.	__class__N)gcZget_referrerstypeobject__setattr__)r]   r^   refsr%   r   r   r   r\     s    
r\   ))r   
__future__r   r   rE   r3   r   rS   rq   rQ   rB   typestypingr   r   r$   Zetilsr   Zetils.ecolabr   ZStrEnumr   cacher   	dataclassr   r   r?   r.   r(   rU   r`   re   ri   r/   rr   FunctionType
MethodTypepropertyrj   r\   r   r   r   r   <module>   sH   
.9