B
    GHZ0$                 @   s   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
mZmZ dd ZdddZd	d
 Zdd ZG dd deZG dd deZG dd deZeedZyed W n  ek
r   ed ed< Y nX ed ed< dddZdS )    N)chain)_log)PY2	iteritems	text_typec              c   s   xt tj D ]} | dkrqt| dd}|rtj|r^tjtj	|dr^tj	|d}d}xLtj
|s|}tj|}||krdP qdW |dd dkr|dd }|V  qW dS )zThis iterates over all relevant Python files.  It goes through all
    loaded files from modules, all files in folders of already loaded modules
    as well as all files reachable through a package.
    N__file__z__init__.py)z.pycz.pyo)listsysmodulesvaluesgetattrospathisdirexistsjoinisfiledirname)modulefilenameold r   1lib/python3.7/site-packages/werkzeug/_reloader.py_iter_module_files   s"    r   c             C   s   t dd tjD }x*| pdD ]}|tjtj| qW xJttj	 D ]8}t
|dd}|dkrjqPtj|}|tj| qPW t|S )z(Finds all paths that should be observed.c             s   s:   | ]2}t j|r&t jt j|n
t j|V  qd S )N)r   r   r   r   abspath).0xr   r   r   	<genexpr>*   s   z)_find_observable_paths.<locals>.<genexpr>r   r   N)setr   r   addr   r   r   r
   r   r   r   _find_common_roots)extra_filesrvr   r   fnr   r   r   _find_observable_paths(   s    r&   c              C   s   t jg} t jd }tjdkr@tj|s@tj|d r@|d7 }tj| d d dkrvtj|d dkrv| d | 	| | 
t jdd  | S )zReturns the executable. This contains a workaround for windows
    if the executable is incorrectly reported to not have the .exe
    extension which can cause bugs on reloading.
    r   ntz.exe   N)r   
executableargvr   namer   r   splitextpopappendextend)r$   Z	py_scriptr   r   r   _get_args_for_reloading;   s    
,

r0   c                sr   dd | D } i }x<t | tddD ]*}|}x|D ]}||i }q0W |  q"W t  fdd  |d S )zAOut of some paths it finds the common roots that need monitoring.c             S   s   g | ]}| tjjqS r   )splitr   r   sep)r   r   r   r   r   
<listcomp>N   s    z&_find_common_roots.<locals>.<listcomp>T)keyreversec                s>   x$t | D ]\}} |||f  q
W | s:d| d S )N/)r   r!   r   )noder   prefixZchild)_walkr$   r   r   r9   X   s    z!_find_common_roots.<locals>._walkr   )sortedlen
setdefaultclearr    )pathsrootZchunksr7   chunkr   )r9   r$   r   r"   L   s    

r"   c               @   sD   e Zd ZdZeejZdddZdd Z	dd Z
d	d
 Zdd ZdS )ReloaderLoopNr(   c             C   s"   t dd |pdD | _|| _d S )Nc             s   s   | ]}t j|V  qd S )N)r   r   r   )r   r   r   r   r   r   j   s   z(ReloaderLoop.__init__.<locals>.<genexpr>r   )r    r#   interval)selfr#   rB   r   r   r   __init__i   s    zReloaderLoop.__init__c             C   s   d S )Nr   )rC   r   r   r   runn   s    zReloaderLoop.runc             C   s   xt dd| j  t }tj }d|d< tjdkrftrfx,t|D ] \}}t|t	rB|
d||< qBW tj||dd}|d	kr|S qW d
S )zuSpawn a new Python interpreter with the same arguments as this one,
        but running the reloader thread.
        infoz * Restarting with %strueWERKZEUG_RUN_MAINr'   z
iso-8859-1F)envZ	close_fds   N)r   r+   r0   r   environcopyr   r   
isinstancer   encode
subprocessZcall)rC   argsZnew_environr4   valueZ	exit_coder   r   r   restart_with_reloaderq   s    

z"ReloaderLoop.restart_with_reloaderc             C   s   |  | td d S )NrJ   )
log_reloadr   exit)rC   r   r   r   r   trigger_reload   s    
zReloaderLoop.trigger_reloadc             C   s   t j|}tdd|  d S )NrF   z# * Detected change in %r, reloading)r   r   r   r   )rC   r   r   r   r   rS      s    zReloaderLoop.log_reload)Nr(   )__name__
__module____qualname__r+   staticmethodtimeZsleep_sleeprD   rE   rR   rU   rS   r   r   r   r   rA   a   s   

rA   c               @   s   e Zd ZdZdd ZdS )StatReloaderLoopstatc          	   C   s   i }xxnt t | jD ]\}yt|j}W n tk
r@   wY nX ||}|d kr`|||< qq||kr| | qW | 	| j
 qW d S )N)r   r   r#   r   r]   st_mtimeOSErrorgetrU   r[   rB   )rC   Zmtimesr   mtimeZold_timer   r   r   rE      s    
zStatReloaderLoop.runN)rV   rW   rX   r+   rE   r   r   r   r   r\      s   r\   c               @   s$   e Zd Zdd Zdd Zdd ZdS )WatchdogReloaderLoopc                s   t jf|| ddlm} ddlm} t _fdd G  fddd|}|j	 }|
drr|d d	 }|d
7 }|_|_| _d_d S )Nr   )Observer)FileSystemEventHandlerc                sH   |  j kr |  tj| }|t jrD| drD |  d S )N)z.pycz.pyoz.py)	r#   rU   r   r   r   
startswithtupleobservable_pathsendswith)r   r   )rC   r   r   _check_modification   s    


z:WatchdogReloaderLoop.__init__.<locals>._check_modificationc                   s<   e Zd Z fddZ fddZ fddZ fddZd	S )
z5WatchdogReloaderLoop.__init__.<locals>._CustomHandlerc                s    |j  d S )N)src_path)rC   event)ri   r   r   
on_created   s    z@WatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_createdc                s    |j  d S )N)rj   )rC   rk   )ri   r   r   on_modified   s    zAWatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_modifiedc                s    |j   |j d S )N)rj   Z	dest_path)rC   rk   )ri   r   r   on_moved   s    
z>WatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_movedc                s    |j  d S )N)rj   )rC   rk   )ri   r   r   
on_deleted   s    z@WatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_deletedN)rV   rW   rX   rl   rm   rn   ro   r   )ri   r   r   _CustomHandler   s   rp   observeriz	 reloaderF)rA   rD   Zwatchdog.observersrc   Zwatchdog.eventsrd   r    rg   rV   lowerrh   r+   observer_classevent_handlershould_reload)rC   rP   kwargsrc   rd   rp   Zreloader_namer   )ri   rC   r   rD      s    

zWatchdogReloaderLoop.__init__c             C   s   d| _ | | d S )NT)ru   rS   )rC   r   r   r   r   rU      s    z#WatchdogReloaderLoop.trigger_reloadc          	   C   s   i }|   }|  zx| jst|}t| j}xV|D ]N}||krzy|j| j|dd||< W n tk
rx   d ||< Y nX |	| q6W x*|D ]"}|
|d }|d k	r|| qW || _| | j qW W d |  |  X td d S )NT)	recursiverJ   )rs   startru   r    r&   r#   Zschedulert   r_   discardr-   Z
unschedulerg   r[   rB   stopr   r   rT   )rC   Zwatchesrq   Z	to_deleter>   r   Zwatchr   r   r   rE      s0    



zWatchdogReloaderLoop.runN)rV   rW   rX   rD   rU   rE   r   r   r   r   rb      s   (rb   )r]   watchdogzwatchdog.observersr]   autor{   r(   c             C   s   ddl }t| ||}| |jdd  yLtjddkrdtj| dd}|d	 |	  |
  nt|  W n tk
r   Y nX dS )
z<Run the given function in an independent python interpreter.r   Nc              W   s
   t dS )Nr   )r   rT   )rP   r   r   r   <lambda>  s    z#run_with_reloader.<locals>.<lambda>rH   rG   r   )targetrP   T)signalreloader_loopsSIGTERMr   rK   r`   	threadingZThreadZ	setDaemonrx   rE   r   rT   rR   KeyboardInterrupt)Z	main_funcr#   rB   Zreloader_typer   Zreloadertr   r   r   run_with_reloader  s    

r   )N)Nr(   r|   )r   r   rZ   rO   r   	itertoolsr   Zwerkzeug._internalr   Zwerkzeug._compatr   r   r   r   r&   r0   r"   objectrA   r\   rb   r   
__import__ImportErrorr   r   r   r   r   <module>   s.   
0S 