U
    (Q^-                     @   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	 ddlm
Z
 ddl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zed W n  ek
r   ed ed< Y nX ed ed< dd Zd ddZdS )!    N)chain   )	iteritems)PY2)	text_type)_logc                  c   s   t tj D ]} | dkrqt| dd}|rtj|r\tjtj	|dr\tj	|d}d}tj
|s|}tj|}||kr`qq`|dd dkr|dd }|V  q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).pyc.pyo)listsysmodulesvaluesgetattrospathisdirexistsjoinisfiledirname)modulefilenameold r   8/tmp/pip-install-bd4o36v9/Werkzeug/werkzeug/_reloader.py_iter_module_files   s$    r   c                 C   s   t dd tjD }| pdD ]}|tjtj| qttj	 D ]8}t
|dd}|dkrdqJtj|}|tj| qJt|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   sd  t jg} t jd }t jdd }t jd }t|dddksjtjdkr|jdkrtj	|stj	|d rtj
|}tjdkrtj	|stj	|d r|d7 }tjt jd dkrtj|d dkr| d | | nrt jd d	krt j}n\tj|r>|j}tjtj|d }|dkrB|d
| 7 }n|}| d	|d
f | | | S )zpDetermine how the script was executed, and return the args needed
    to execute it again in a new process.
    r   r   N__main____package__nt z.exez-m.)r   
executableargvr   r   r   namer-   r   r   r    splitextpopappendr   basenameextendlstrip)r)   Z	py_scriptargsr,   Z	py_moduler3   r   r   r   _get_args_for_reloading?   sD    






r;   c                    sj   dd | D } i }t | tddD ]&}|}|D ]}||i }q,|  q 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   sepr!   r   r   r   
<listcomp>}   s     z&_find_common_roots.<locals>.<listcomp>T)keyreversec                    s:   t | D ]\}} |||f  q| s6d| d S )N/)r   r&   r   )noder   prefixchild_walkr)   r   r   rF      s    z!_find_common_roots.<locals>._walkr   )sortedlen
setdefaultclearr%   )pathsrootchunksrB   chunkr   rE   r   r'   {   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 r   )r   r   r    r!   r   r   r   r$      s     z(ReloaderLoop.__init__.<locals>.<genexpr>r   )r%   r(   interval)selfr(   rP   r   r   r   __init__   s    zReloaderLoop.__init__c                 C   s   d S r   r   rQ   r   r   r   run   s    zReloaderLoop.runc                 C   s   t dd| j  t }tjdkrntrni }ttjD ]8\}}t|trN|	d}t|trb|	d}|||< q2n
tj
 }d|d< tj||dd}|d	kr |S q d
S )zuSpawn a new Python interpreter with the same arguments as this one,
        but running the reloader thread.
        infoz * Restarting with %sr.   z
iso-8859-1trueWERKZEUG_RUN_MAINF)env	close_fds   N)r   r3   r;   r   r   r   environ
isinstancer   encodecopy
subprocesscall)rQ   r:   Znew_environr?   valueZ	exit_coder   r   r   restart_with_reloader   s    




z"ReloaderLoop.restart_with_reloaderc                 C   s   |  | td d S )NrZ   )
log_reloadr   exitrQ   r   r   r   r   trigger_reload   s    
zReloaderLoop.trigger_reloadc                 C   s   t j|}tdd|  d S )NrU   z# * Detected change in %r, reloading)r   r   r    r   re   r   r   r   rc      s    zReloaderLoop.log_reload)Nr   )__name__
__module____qualname__r3   staticmethodtimesleep_sleeprR   rT   rb   rf   rc   r   r   r   r   rO      s   

rO   c                   @   s   e Zd ZdZdd ZdS )StatReloaderLoopstatc              	   C   s   i }t t | jD ]^}zt|j}W n tk
r>   Y qY nX ||}|d kr^|||< qq||kr| | q| 	| j
 qd S r   )r   r   r(   r   ro   st_mtimeOSErrorgetrf   rm   rP   )rQ   Zmtimesr   mtimeZold_timer   r   r   rT      s    

zStatReloaderLoop.runN)rg   rh   ri   r3   rT   r   r   r   r   rn      s   rn   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)r
   r   z.py)	r(   rf   r   r   r   
startswithtupleobservable_pathsendswith)r   r   rS   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 r   src_pathrQ   eventr{   r   r   
on_created   s    z@WatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_createdc                    s    |j  d S r   r|   r~   r   r   r   on_modified   s    zAWatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_modifiedc                    s    |j   |j d S r   )r}   	dest_pathr~   r   r   r   on_moved   s    
z>WatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_movedc                    s    |j  d S r   r|   r~   r   r   r   
on_deleted   s    z@WatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_deletedN)rg   rh   ri   r   r   r   r   r   r   r   r   _CustomHandler   s   r   observeriz	 reloaderF)rO   rR   Zwatchdog.observersru   Zwatchdog.eventsrv   r%   ry   rg   lowerrz   r3   observer_classevent_handlershould_reload)rQ   r:   kwargsru   rv   r   Zreloader_namer   )r{   rQ   r   rR      s    

zWatchdogReloaderLoop.__init__c                 C   s   d| _ | | d S )NT)r   rc   re   r   r   r   rf     s    z#WatchdogReloaderLoop.trigger_reloadc              	   C   s   i }|   }|  z| jst|}t| j}|D ]N}||krvz|j| j	|dd||< W n t
k
rt   d ||< Y nX || q2|D ]"}||d }|d k	r|| q|| _| | j qW 5 |  |  X td d S )NT)	recursiverZ   )r   startstopr   r   r%   r+   r(   scheduler   rq   discardr5   Z
unschedulery   rm   rP   r   rd   )rQ   Zwatchesr   Z	to_deleterK   r   Zwatchr   r   r   rT   	  s6    
  
zWatchdogReloaderLoop.runN)rg   rh   ri   rR   rf   rT   r   r   r   r   rt      s   (rt   )ro   watchdogzwatchdog.observersro   autor   c                  C   st   t j sdS zddl} W n tk
r0   Y dS X | t j}|d | j@ sp|d  | jO  < | t j| j| dS )zsEnsure that echo mode is enabled. Some tools such as PDB disable
    it which causes usability issues after reload.Nr   rZ   )	r   stdinisattytermiosImportError	tcgetattrECHO	tcsetattrTCSANOW)r   
attributesr   r   r   ensure_echo_on5  s    
r   c                 C   s   ddl }t| ||}| |jdd  zRtjddkrjt  t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   rd   )r:   r   r   r   <lambda>J      z#run_with_reloader.<locals>.<lambda>rW   rV   r   )targetr:   T)signalreloader_loopsSIGTERMr   r[   rr   r   	threadingThread	setDaemonr   rT   r   rd   rb   KeyboardInterrupt)Z	main_funcr(   rP   Zreloader_typer   Zreloadertr   r   r   run_with_reloaderE  s    

r   )N)Nr   r   )r   r_   r   r   rk   	itertoolsr   _compatr   r   r   	_internalr   r   r+   r;   r'   objectrO   rn   rt   r   
__import__r   r   r   r   r   r   r   <module>   s0   
<3R
