o
    \Oc7                     @   sP  U 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jejhZh eejejZeedrLeej eeZ[h dZdeje fd	d
Zdeje deje ddfddZdeje deje deje fddZdeje deje deje fddZ deje deje fddZ!dej"e fddZ#G dd dZ$G dd de$Z%G dd de$Z&e%e&dZ'ej(eej)e$ f e*d< ze+d  W n e,y   e'd! e'd"< Y nw e'd# e'd"< d+d$d%Z-				"d,d&ej.g df dej/eje  dej/eje  d'ej0e1e2f d(eddfd)d*Z3dS )-    N)chain)PurePath   )_logreal_prefix>   z.gitz.mypy_cache__pycache__z.toxz.pytest_cachez.hgz.noxreturnc                  c   sr    t tj D ].} t| dd}|du s|trqtj	|s3|}tj
|}||kr-n	tj	|r |V  qdS )z;Find the filesystem paths associated with imported modules.__file__N)listsysmodulesvaluesgetattr
startswith_ignore_alwaysospathisfiledirname)modulenameold r   4D:\Flask\env\Lib\site-packages\werkzeug/_reloader.py_iter_module_paths&   s   r   pathsexclude_patternsc                 C   s    |D ]}|  t| | qd S N)difference_updatefnmatchfilter)r   r   patternr   r   r   _remove_by_pattern:   s   r"   extra_filesc           
   	   C   s   t  }tttj| D ]d}tj|}tj|r|| qtj	|di}t
|D ]B\}}}|ts>tj|tv rC|  q,d}|D ]}	|	drZd}|tj||	 qG|sj|tj	| sj|  q,|||< q,q|t  t|| |S )ax  Find paths for the stat reloader to watch. Returns imported
    module files, Python files under non-system paths. Extra files and
    Python files under extra directories can also be scanned.

    System paths have to be excluded for efficiency. Non-system paths,
    such as a project root or ``sys.path.insert``, should be the paths
    of interest to the user anyway.
    TF)z.pyz.pyc)setr   r
   r   r   r   abspathr   addr   walkr   _stat_ignore_scanbasename_ignore_common_dirsclearendswithjoinupdater   r"   )
r#   r   r   r   Zparent_has_pyrootdirsfilesZhas_pyr   r   r   r   _find_stat_paths?   s8   



r2   c                 C   sz   t  }tttj| D ]}tj|}tj|rtj|}|	| qt
 D ]}|	tj| q(t|| t|S )zFind paths for the stat reloader to watch. Looks at the same
    sources as the stat reloader, but watches everything under
    directories instead of individual files.
    )r$   r   r
   r   r   r   r%   r   r   r&   r   r"   _find_common_roots)r#   r   r0   r   r   r   r   _find_watchdog_pathsu   s   

r4   c                    s   i }t dd | D tddD ]}|}|D ]}||i }q|  qt dtjttf dtj	tdf dd f fd	d
  |d S )Nc                 s   s    | ]}t |jV  qd S r   )r   parts.0xr   r   r   	<genexpr>   s    z%_find_common_roots.<locals>.<genexpr>T)keyreversenoder   .r   c                    s@   |   D ]\}} |||f  q| stjj|  d S d S r   )itemsr&   r   r   r-   )r<   r   prefixchild_walkrvr   r   rA      s
   z!_find_common_roots.<locals>._walkr   )
sortedlen
setdefaultr+   r$   tMappingstrdictTuple)r   r/   chunksr<   chunkr   r@   r   r3      s   
0
r3   c                  C   sX  t jg} t jd }t jdd }t jd }t|dddu s6tjdkrt|jdkrttj	|sttj	| drttj
|}tjdkrntj	|sTtj	| drT|d7 }tjt jd dkrntj|d dkrn| d | | n1tj|rtt|j}tjtj|d }|dkr|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.exe.z-m)r   
executableargvr   r   r   r   rN   r   existsr%   splitextpopappendr   rF   castrH   r)   extendlstrip)rB   Z	py_scriptargsrM   Z	py_moduler   r   r   r   _get_args_for_reloading   sB   





r\   c                	   @   s   e Zd ZdZ			ddejeje  dejeje  deje	e
f ddfdd	Zdd
dZdd ZdddZdddZde	fddZdeddfddZdeddfddZdS )ReloaderLooprP   Nr   r#   r   intervalr   c                 C   s,   dd |pdD | _ t|pd| _|| _d S )Nc                 S   s   h | ]}t j|qS r   )r   r   r%   r6   r   r   r   	<setcomp>       z(ReloaderLoop.__init__.<locals>.<setcomp>r   )r#   r$   r   r^   )selfr#   r   r^   r   r   r   __init__   s   
zReloaderLoop.__init__c                 C   s   |    | S )zgDo any setup, then run one step of the watch to populate the
        initial filesystem state.
        )run_stepra   r   r   r   	__enter__   s   zReloaderLoop.__enter__c                 C      dS )z4Clean up any resources associated with the reloader.Nr   ra   exc_typeexc_valexc_tbr   r   r   __exit__   s   zReloaderLoop.__exit__c                 C   s   	 |    t| j q)zfContinually run the watch step, sleeping for the configured
        interval after each step.
        )rc   timesleepr^   rd   r   r   r   run   s   zReloaderLoop.runc                 C   rf   )z}Run one step for watching the filesystem. Called once to set
        up initial state, then repeatedly to update it.
        Nr   rd   r   r   r   rc      s   zReloaderLoop.run_stepc                 C   sJ   	 t dd| j  t }tj }d|d< tj||dd}|dkr$|S q)	z|Spawn a new Python interpreter with the same arguments as the
        current one, but running the reloader thread.
        Tinfoz * Restarting with trueWERKZEUG_RUN_MAINF)env	close_fds   )r   r   r\   r   environcopy
subprocesscall)ra   r[   Znew_environ	exit_coder   r   r   restart_with_reloader  s   
z"ReloaderLoop.restart_with_reloaderfilenamec                 C   s   |  | td d S Nrt   )
log_reloadr   exitra   r{   r   r   r   trigger_reload     
zReloaderLoop.trigger_reloadc                 C   s"   t j|}tdd|d d S )Nro   z * Detected change in z, reloading)r   r   r%   r   r   r   r   r   r}     s   zReloaderLoop.log_reload)NNr   )r   r]   r   N)__name__
__module____qualname__r   rF   OptionalIterablerH   Unionintfloatrb   re   rk   rn   rc   rz   r   r}   r   r   r   r   r]      s*    




r]   c                       s0   e Zd ZdZdef fddZdddZ  ZS )	StatReloaderLoopstatr   c                    s   i | _ t  S r   )mtimessuperre   rd   	__class__r   r   re     s   
zStatReloaderLoop.__enter__Nc              	   C   sn   t | j| jD ]-}zt|j}W n	 ty   Y qw | j|}|d u r+|| j|< q||kr4| 	| qd S r   )
r2   r#   r   r   r   st_mtimeOSErrorr   getr   )ra   r   mtimeZold_timer   r   r   rc     s   

zStatReloaderLoop.run_stepr   )r   r   r   r   r]   re   rc   __classcell__r   r   r   r   r     s    r   c                       sn   e Zd Zdejdejddf fddZdeddfdd	Zdef fd
dZ	dd Z
dddZdddZ  ZS )WatchdogReloaderLoopr[   kwargsr   Nc                    s   ddl m} ddlm} t j|i | | j G  fddd|}|j }|	dr2|d d }d| d	| _
| | _d
d | jD }|dddg|g dd tD | jd| _d| _d S )Nr   )Observer)PatternMatchingEventHandlerc                       s   e Zd Z fddZdS )z3WatchdogReloaderLoop.__init__.<locals>.EventHandlerc                    s    |j  d S r   )Zsrc_path)ra   eventr   r   r   on_any_event9  s   z@WatchdogReloaderLoop.__init__.<locals>.EventHandler.on_any_eventN)r   r   r   r   r   r   r   r   EventHandler8  s    r   observeriz
watchdog ()c                 S   s   g | ]
}t j|s|qS r   )r   r   isdir)r7   pr   r   r   
<listcomp>H  s    z1WatchdogReloaderLoop.__init__.<locals>.<listcomp>z*.pyz*.pycz*.zipc                 S   s   g | ]}d | dqS )z*/z/*r   )r7   dr   r   r   r   L  r`   )patternsignore_patternsF)Zwatchdog.observersr   Zwatchdog.eventsr   r   rb   r   r   lowerr,   r   r   r#   r*   r   event_handlershould_reload)ra   r[   r   r   r   r   Zreloader_nameZextra_patternsr   r   r   rb   1  s(   


zWatchdogReloaderLoop.__init__r{   c                 C   s   d| _ | | d S )NT)r   r}   r   r   r   r   r   R  s   z#WatchdogReloaderLoop.trigger_reloadc                    s   i | _ | j  t  S r   )watchesr   startr   re   rd   r   r   r   re   Y  s   

zWatchdogReloaderLoop.__enter__c                 C   s   | j   | j   d S r   )r   stopr-   rg   r   r   r   rk   ^  r   zWatchdogReloaderLoop.__exit__c                 C   s.   | j s|   t| j | j rtd d S r|   )r   rc   rl   rm   r^   r   r~   rd   r   r   r   rn   b  s
   zWatchdogReloaderLoop.runc              	   C   s   t | j}t| j| jD ]*}|| jvr1z| jj| j|dd| j|< W n ty0   d | j|< Y nw |	| q|D ]}| j
|d }|d urL| j| q9d S )NT)	recursive)r$   r   r4   r#   r   r   Zscheduler   r   discardrV   Z
unschedule)ra   Z	to_deleter   watchr   r   r   rc   i  s"   

zWatchdogReloaderLoop.run_stepr   )r   r   r   rF   Anyrb   rH   r   r]   re   rk   rn   rc   r   r   r   r   r   r   0  s    !
r   )r   watchdogreloader_loopszwatchdog.observersr   autor   c                  C   s   t jdu s
t j sdS zddl} W n
 ty   Y dS w | t j}|d | j@ s>|d  | jO  < | t j| j| dS dS )zuEnsure that echo mode is enabled. Some tools such as PDB disable
    it which causes usability issues after a reload.Nr   rt   )	r   stdinisattytermiosImportError	tcgetattrECHO	tcsetattrZTCSANOW)r   
attributesr   r   r   ensure_echo_on  s   r   	main_funcr^   reloader_typec                 C   s   ddl }| |jdd  t| |||d}z>tjddkrKt  tj| dd	}d
|_	| |
  |  W d   W dS 1 sCw   Y  W dS t|  W dS  ty^   Y dS w )z<Run the given function in an independent Python interpreter.r   Nc                  W   s
   t dS )Nr   )r   r~   )r[   r   r   r   <lambda>  s   
 z#run_with_reloader.<locals>.<lambda>)r#   r   r^   rq   rp   r   )targetr[   T)signalSIGTERMr   r   ru   r   r   	threadingThreaddaemonr   rn   r   r~   rz   KeyboardInterrupt)r   r#   r   r^   r   r   ZreloaderrF   r   r   r   run_with_reloader  s$   
&r   r   )NNr   r   )4r   r   rw   r   r   rl   typingrF   	itertoolsr   pathlibr   	_internalr   tuplebase_prefixbase_exec_prefixr   r>   exec_prefixhasattrr&   r   r(   r*   IteratorrH   r   Setr"   r   r2   r4   r3   Listr\   r]   r   r   r   DictType__annotations__
__import__r   r   Callabler   r   r   r   r   r   r   r   r   <module>   s   
 
"
6
6=R
