
À«‘_-  ã               @   sw  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 Gd d „  d e ƒ Z Gd d „  d e ƒ Z Gd d „  d e ƒ Z d e d e i Z y e d ƒ Wn  e k
 rCe d e d <Yn Xe d e d <d d „  Z d d d d d „ Z d S)é    N)Úchainé   )Ú	iteritems)ÚPY2)Ú	text_type)Ú_logc              c   s  xû t  t j j ƒ  ƒ D]ä }  |  d k r+ q t |  d d ƒ } | r t j j | ƒ r‹ t j j t j j	 | d ƒ ƒ r‹ t j j	 | d ƒ } d } xf t j j
 | ƒ sÎ | } t j j | ƒ } | | k r” Pq” W| d d … d	 k rõ | d d
 … } | Vq Wd S)zËThis 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ú.pyor   éüÿÿÿ)r
   r   éÿÿÿÿ)ÚlistÚsysÚmodulesÚvaluesÚgetattrÚosÚpathÚisdirÚexistsÚjoinÚisfileÚdirname)ÚmoduleÚfilenameÚold© r   ú6/tmp/pip-build-5gj8f0j9/Werkzeug/werkzeug/_reloader.pyÚ_iter_module_files   s"    r   c             C   sÎ   t  d d „  t j Dƒ ƒ } x9 |  p( f  D]+ } | j t j j t j j | ƒ ƒ ƒ q) Wxi t t j j	 ƒ  ƒ D]R } t
 | d d ƒ } | d k r• qn t j j | ƒ } | j t j j | ƒ ƒ qn Wt | ƒ S)z(Finds all paths that should be observed.c             s   sQ   |  ]G } t  j j | ƒ r9 t  j j t  j j | ƒ ƒ n t  j j | ƒ Vq d  S)N)r   r   r   r   Úabspath)Ú.0Úxr   r   r   ú	<genexpr>.   s   z)_find_observable_paths.<locals>.<genexpr>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 d … } t  j d } t | d d ƒ d k s˜ t j d k rD| j d k rDt j j	 | ƒ rDt j j	 | d ƒ rDt j j
 | ƒ } t j d k r4t j j	 | ƒ rì t j j	 | d ƒ rì | d 7} t j j t  j ƒ d d k r4t j j | ƒ d d k r4|  j d ƒ |  j | ƒ n› t  j d d	 k rct  j } n| t j j | ƒ r½| j } t j j t j j | ƒ ƒ d } | d k rÃ| d
 | 7} n | } |  j d	 | j d
 ƒ f ƒ |  j | ƒ |  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_moduler2   r   r   r   Ú_get_args_for_reloading?   s8    )
	"r:   c                sž   d d „  |  Dƒ }  i  } xS t  |  d t d d ƒD]9 } | } x  | D] } | j | i  ƒ } qE W| j ƒ  q2 Wt ƒ  ‰ ‡  ‡ f d d †  ‰  ˆ  | f  ƒ ˆ S)zAOut of some paths it finds the common roots that need monitoring.c             S   s%   g  |  ] } | j  t j j ƒ ‘ q Sr   )Úsplitr   r   Úsep)r!   r"   r   r   r   ú
<listcomp>}   s   	 z&_find_common_roots.<locals>.<listcomp>ÚkeyÚreverseTc                sQ   x. t  |  ƒ D]  \ } } ˆ  | | | f ƒ q W|  sM ˆ j d j | ƒ ƒ d  S)Nú/)r   r%   r   )Únoder   ÚprefixÚchild)Ú_walkr(   r   r   rD   ‡   s    z!_find_common_roots.<locals>._walk)ÚsortedÚlenÚ
setdefaultÚclearr$   )ÚpathsÚrootÚchunksrA   Úchunkr   )rD   r(   r   r&   {   s    	r&   c               @   sg   e  Z d  Z d Z e e j ƒ Z d 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 f  Dƒ ƒ |  _ | |  _ d  S)Nc             s   s!   |  ] } t  j j | ƒ Vq d  S)N)r   r   r    )r!   r"   r   r   r   r#   š   s    z(ReloaderLoop.__init__.<locals>.<genexpr>)r$   r'   Úinterval)Úselfr'   rN   r   r   r   Ú__init__™   s    "zReloaderLoop.__init__c             C   s   d  S)Nr   )rO   r   r   r   Úrun�   s    zReloaderLoop.runc             C   sð   xé t  d d |  j ƒ t ƒ  } t j d k r¤ t r¤ i  } xu t t j ƒ D]R \ } } t | t ƒ ru | j	 d ƒ } t | t ƒ r“ | j	 d ƒ } | | | <qK Wn t j j
 ƒ  } d | d <t j | d | d d	 ƒ} | d
 k r | Sq Wd 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_MAINÚenvÚ	close_fdsFé   N)r   r2   r:   r   r   r   ÚenvironÚ
isinstancer   ÚencodeÚcopyÚ
subprocessÚcall)rO   r9   Znew_environr>   ÚvalueZ	exit_coder   r   r   Úrestart_with_reloader    s     	
z"ReloaderLoop.restart_with_reloaderc             C   s   |  j  | ƒ t j d ƒ d  S)NrW   )Ú
log_reloadr   Úexit)rO   r   r   r   r   Útrigger_reload»   s    zReloaderLoop.trigger_reloadc             C   s'   t  j j | ƒ } t d d | ƒ d  S)NrR   z# * Detected change in %r, reloading)r   r   r    r   )rO   r   r   r   r   r`   ¿   s    zReloaderLoop.log_reload)Ú__name__Ú
__module__Ú__qualname__r2   ÚstaticmethodÚtimeÚsleepÚ_sleeprP   rQ   r_   rb   r`   r   r   r   r   rM   ‘   s   rM   c               @   s"   e  Z d  Z d Z d d „  Z d S)ÚStatReloaderLoopÚstatc             C   s³   i  } x¦ x� t  t ƒ  |  j ƒ D]x } y t j | ƒ j } Wn t k
 rR w Yn X| j | ƒ } | d  k r~ | | | <q q | | k r |  j | ƒ q W|  j	 |  j
 ƒ q	 Wd  S)N)r   r   r'   r   rk   Úst_mtimeÚOSErrorÚgetrb   ri   rN   )rO   Zmtimesr   ÚmtimeZold_timer   r   r   rQ   Ç   s    
zStatReloaderLoop.runN)rc   rd   re   r2   rQ   r   r   r   r   rj   Ä   s   rj   c               @   s4   e  Z d  Z d d „  Z d d „  Z d d „  Z d S)ÚWatchdogReloaderLoopc                sÐ   t  j ˆ | | Ž d d l m } d d l m } t ƒ  ˆ _ ‡ f d d †  ‰  G‡  f d d †  d | ƒ } | j j	 ƒ  } | j
 d ƒ r› | d  d … } | d
 7} | ˆ _ | ˆ _ | ƒ  ˆ _ d ˆ _ d  S)Nr   )ÚObserver)ÚFileSystemEventHandlerc                sf   |  ˆ  j  k r ˆ  j |  ƒ t j j |  ƒ } | j t ˆ  j ƒ ƒ rb |  j d ƒ rb ˆ  j |  ƒ d  S)Nú.pycú.pyoú.py)rs   rt   ru   )	r'   rb   r   r   r   Ú
startswithÚtupleÚobservable_pathsÚendswith)r   r   )rO   r   r   Ú_check_modificationá   s    z:WatchdogReloaderLoop.__init__.<locals>._check_modificationc                   sX   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)rO   Úevent)rz   r   r   Ú
on_createdê   s    z@WatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_createdc                s   ˆ  | j  ƒ d  S)N)r{   )rO   r|   )rz   r   r   Úon_modifiedí   s    zAWatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_modifiedc                s   ˆ  | j  ƒ ˆ  | j ƒ d  S)N)r{   Z	dest_path)rO   r|   )rz   r   r   Úon_movedð   s    z>WatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_movedc                s   ˆ  | j  ƒ d  S)N)r{   )rO   r|   )rz   r   r   Ú
on_deletedô   s    z@WatchdogReloaderLoop.__init__.<locals>._CustomHandler.on_deletedN)rc   rd   re   r}   r~   r   r€   r   )rz   r   r   Ú_CustomHandleré   s   r�   Úobserveré   z	 reloaderFiøÿÿÿ)rM   rP   Zwatchdog.observersrq   Zwatchdog.eventsrr   r$   rx   rc   Úlowerry   r2   Úobserver_classÚevent_handlerÚshould_reload)rO   r9   Úkwargsrq   rr   r�   Zreloader_namer   )rz   rO   r   rP   Ú   s    
		zWatchdogReloaderLoop.__init__c             C   s   d |  _  |  j | ƒ d  S)NT)r‡   r`   )rO   r   r   r   r   rb     s    	z#WatchdogReloaderLoop.trigger_reloadc             C   s5  i  } |  j  ƒ  } | j ƒ  zð xé |  j s
t | ƒ } t |  j ƒ } xi | D]a } | | k r¡ y# | j |  j | d d ƒ| | <Wn t k
 r  d  | | <Yn X| j	 | ƒ qM Wx9 | D]1 } | j
 | d  ƒ } | d  k	 r¹ | j | ƒ q¹ W| |  _ |  j |  j ƒ q" WWd  | j ƒ  | j ƒ  Xt j d ƒ d  S)NÚ	recursiveTrW   )r…   Ústartr‡   r$   r*   r'   Úscheduler†   rm   Údiscardr4   Z
unschedulerx   ri   rN   Ústopr   r   ra   )rO   Zwatchesr‚   Z	to_deleterI   r   Zwatchr   r   r   rQ   	  s0    
	
zWatchdogReloaderLoop.runN)rc   rd   re   rP   rb   rQ   r   r   r   r   rp   Ù   s   (rp   rk   Zwatchdogzwatchdog.observersZautoc              C   s�   t  j j ƒ  s d Sy d d l }  Wn t k
 r; d SYn X|  j t  j ƒ } | d |  j @s‰ | d |  j O<|  j 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   rW   )	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  | j d d „  ƒ yr t j j d ƒ d k r– t ƒ  t j d |  d f  ƒ } | j	 d	 ƒ | j
 ƒ  | j ƒ  n t j | j ƒ  ƒ Wn t k
 r¾ Yn Xd S)
z<Run the given function in an independent python interpreter.r   Nc              W   s   t  j d ƒ S)Nr   )r   ra   )r9   r   r   r   Ú<lambda>J  s    z#run_with_reloader.<locals>.<lambda>rT   rS   Útargetr9   T)ÚsignalÚreloader_loopsÚSIGTERMr   rX   rn   r—   Ú	threadingÚThreadÚ	setDaemonrŠ   rQ   r   ra   r_   ÚKeyboardInterrupt)Z	main_funcr'   rN   Zreloader_typerš   ZreloaderÚtr   r   r   Úrun_with_reloaderE  s    
r¢   )r   r\   r   r�   rg   Ú	itertoolsr   Ú_compatr   r   r   Z	_internalr   r   r*   r:   r&   ÚobjectrM   rj   rp   r›   Ú
__import__r‘   r—   r¢   r   r   r   r   Ú<module>   s0   <3R