o
    h8                      @   s  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mZmZmZmZmZ d dlZddlmZ ddlmZ dZe d	ZG d
d deZeeef Z	 e	rxd dlZd dlmZ d dlZeejejejf Z G dd deZ!e dddddddddddddeeef deedege"f  de#de#ded de#de"dee" de"dee" d e#d!e"d"ee" d#eee ddf fd$d%Z$e dddddddddddddeeef deeeege"f  de#de#ded& dee# de"dee" dee" dee" d e#d!e"d"ee" d#e
ee df fd'd(Z%d)eee#ef  deeeege"f  d#ee fd*d+Z&d,ee d#dfd-d.Z'd/ee# d#e#fd0d1Z(dee" d#e"fd2d3Z)dee" d#e"fd4d5Z*d#e"fd6d7Z+d"ee" d#e"fd8d9Z,dS ):    N)IntEnum)Path)TYPE_CHECKINGAsyncGeneratorCallable	GeneratorOptionalSetTupleUnion   )
RustNotify)DefaultFilter)watchawatchChange
FileChangezwatchfiles.mainc                   @   s0   e Zd ZdZdZ	 dZ	 dZ	 defddZdS )	r   z=
    Enum representing the type of change that occurred.
    r         returnc                 C   s   | j S N)nameself r   G/var/www/html/zoom/venv/lib/python3.10/site-packages/watchfiles/main.pyraw_str   s   zChange.raw_strN)	__name__
__module____qualname____doc__addedmodifieddeletedstrr   r   r   r   r   r      s    r   )Protocolc                   @   s   e Zd ZdefddZdS )AbstractEventr   c                 C   s   d S r   r   r   r   r   r   is_set1   s    zAbstractEvent.is_setN)r   r   r   boolr'   r   r   r   r   r&   0   s    r&   i@  2     FTi,  )watch_filterdebouncestep
stop_eventrust_timeoutyield_on_timeoutdebugraise_interruptforce_pollingpoll_delay_ms	recursiveignore_permission_deniedpathsr+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r   c                 g   s    t |}t|}t|}tdd |D |||	|
|T}	 |||||}|dkr6|r0t V  n>td n8|dkrL|r>tt	d 	 W d   dS |d	krY	 W d   dS t
|| }|rht| |V  ntd
| q1 srw   Y  dS )a  
    Watch one or more paths and yield a set of changes whenever files change.

    The paths watched can be directories or files, directories are watched recursively - changes in subdirectories
    are also detected.

    #### Force polling

    Notify will fall back to file polling if it can't use file system notifications, but we also force Notify
    to use polling if the `force_polling` argument is `True`; if `force_polling` is unset (or `None`), we enable
    force polling thus:

    * if the `WATCHFILES_FORCE_POLLING` environment variable exists and is not empty:
        * if the value is `false`, `disable` or `disabled`, force polling is disabled
        * otherwise, force polling is enabled
    * otherwise, we enable force polling only if we detect we're running on WSL (Windows Subsystem for Linux)

    Args:
        *paths: filesystem paths to watch.
        watch_filter: callable used to filter out changes which are not important, you can either use a raw callable
            or a [`BaseFilter`][watchfiles.BaseFilter] instance,
            defaults to an instance of [`DefaultFilter`][watchfiles.DefaultFilter]. To keep all changes, use `None`.
        debounce: maximum time in milliseconds to group changes over before yielding them.
        step: time to wait for new changes in milliseconds, if no changes are detected in this time, and
            at least one change has been detected, the changes are yielded.
        stop_event: event to stop watching, if this is set, the generator will stop iteration,
            this can be anything with an `is_set()` method which returns a bool, e.g. `threading.Event()`.
        rust_timeout: maximum time in milliseconds to wait in the rust code for changes, `0` means no timeout.
        yield_on_timeout: if `True`, the generator will yield upon timeout in rust even if no changes are detected.
        debug: whether to print information about all filesystem changes in rust to stdout, if `None` will use the
            `WATCHFILES_DEBUG` environment variable.
        raise_interrupt: whether to re-raise `KeyboardInterrupt`s, or suppress the error and just stop iterating.
        force_polling: See [Force polling](#force-polling) above.
        poll_delay_ms: delay between polling for changes, only used if `force_polling=True`.
        recursive: if `True`, watch for changes in sub-directories recursively, otherwise watch only for changes in the
            top-level directory, default is `True`.
        ignore_permission_denied: if `True`, will ignore permission denied errors, otherwise will raise them by default.
            Setting the `WATCHFILES_IGNORE_PERMISSION_DENIED` environment variable will set this value too.

    Yields:
        The generator yields sets of [`FileChange`][watchfiles.main.FileChange]s.

    ```py title="Example of watch usage"
    from watchfiles import watch

    for changes in watch('./first/dir', './second/dir', raise_interrupt=False):
        print(changes)
    ```
    c                 S      g | ]}t |qS r   r$   .0pr   r   r   
<listcomp>x       zwatch.<locals>.<listcomp>Ttimeoutrust notify timeout, continuingsignalz(KeyboardInterrupt caught, stopping watchNstop(all changes filtered out, raw_changes=%s)_default_force_polling!_default_ignore_permission_denied_default_debugr   r   setloggerr1   KeyboardInterruptwarning_prep_changes_log_changes)r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   watcherraw_changeschangesr   r   r   r   4   s<   @


r   AnyEventc                 G  s  |durt dt |du rt }n|}t|}t|}t|}tdd |D |||	|
|}t	|}t
 }	 t 4 I dH /}ztj|j||||I dH }W n |tfya   |   w |j  W d  I dH  n1 I dH sww   Y  |dkr|rt V  n0td n*|dkr	 W d   dS |d	krtd
t|| }|rt| |V  ntd| q:1 sw   Y  dS )a  
    Asynchronous equivalent of [`watch`][watchfiles.watch] using threads to wait for changes.
    Arguments match those of [`watch`][watchfiles.watch] except `stop_event`.

    All async methods use [anyio](https://anyio.readthedocs.io/en/latest/) to run the event loop.

    Unlike [`watch`][watchfiles.watch] `KeyboardInterrupt` cannot be suppressed by `awatch` so they need to be caught
    where `asyncio.run` or equivalent is called.

    Args:
        *paths: filesystem paths to watch.
        watch_filter: matches the same argument of [`watch`][watchfiles.watch].
        debounce: matches the same argument of [`watch`][watchfiles.watch].
        step: matches the same argument of [`watch`][watchfiles.watch].
        stop_event: `anyio.Event` which can be used to stop iteration, see example below.
        rust_timeout: matches the same argument of [`watch`][watchfiles.watch], except that `None` means
            use `1_000` on Windows and `5_000` on other platforms thus helping with exiting on `Ctrl+C` on Windows,
            see [#110](https://github.com/samuelcolvin/watchfiles/issues/110).
        yield_on_timeout: matches the same argument of [`watch`][watchfiles.watch].
        debug: matches the same argument of [`watch`][watchfiles.watch].
        raise_interrupt: This is deprecated, `KeyboardInterrupt` will cause this coroutine to be cancelled and then
            be raised by the top level `asyncio.run` call or equivalent, and should be caught there.
            See [#136](https://github.com/samuelcolvin/watchfiles/issues/136)
        force_polling: if true, always use polling instead of file system notifications, default is `None` where
            `force_polling` is set to `True` if the `WATCHFILES_FORCE_POLLING` environment variable exists.
        poll_delay_ms: delay between polling for changes, only used if `force_polling=True`.
        recursive: if `True`, watch for changes in sub-directories recursively, otherwise watch only for changes in the
            top-level directory, default is `True`.
        ignore_permission_denied: if `True`, will ignore permission denied errors, otherwise will raise them by default.
            Setting the `WATCHFILES_IGNORE_PERMISSION_DENIED` environment variable will set this value too.

    Yields:
        The generator yields sets of [`FileChange`][watchfiles.main.FileChange]s.

    ```py title="Example of awatch usage"
    import asyncio
    from watchfiles import awatch

    async def main():
        async for changes in awatch('./first/dir', './second/dir'):
            print(changes)

    if __name__ == '__main__':
        try:
            asyncio.run(main())
        except KeyboardInterrupt:
            print('stopped via KeyboardInterrupt')
    ```

    ```py title="Example of awatch usage with a stop event"
    import asyncio
    from watchfiles import awatch

    async def main():
        stop_event = asyncio.Event()

        async def stop_soon():
            await asyncio.sleep(3)
            stop_event.set()

        stop_soon_task = asyncio.create_task(stop_soon())

        async for changes in awatch('/path/to/dir', stop_event=stop_event):
            print(changes)

        # cleanup by awaiting the (now complete) stop_soon_task
        await stop_soon_task

    asyncio.run(main())
    ```
    Nzraise_interrupt is deprecated, KeyboardInterrupt will cause this coroutine to be cancelled and then be raised by the top level asyncio.run call or equivalent, and should be caught there. See #136.c                 S   r8   r   r9   r:   r   r   r   r=      r>   zawatch.<locals>.<listcomp>Tr?   r@   rB   rA   z+watch thread unexpectedly received a signalrC   )warningswarnDeprecationWarninganyioEventrD   rE   rF   r   _calc_async_timeoutget_cancelled_exc_classcreate_task_group	to_threadrun_syncr   rI   rG   cancel_scopecancelrH   r1   RuntimeErrorrK   rL   )r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   stop_event_rM   r?   CancelledErrortgrN   rO   r   r   r   r      sX   V
 (	

r   rN   c                    s(   dd | D } r fdd|D }|S )Nc                 S   s   h | ]
\}}t ||fqS r   )r   )r;   changepathr   r   r   	<setcomp>  s    z _prep_changes.<locals>.<setcomp>c                    s"   h | ]} |d  |d r|qS )r   r   r   )r;   cr+   r   r   rc      s   " r   )rN   r+   rO   r   re   r   rK     s   rK   rO   c                 C   sZ   t tjr+t| }|dkrdnd}t tjr"t d|||  d S t d|| d S d S )Nr    sz%d change%s detected: %sz%d change%s detected)rH   isEnabledForloggingINFOlenDEBUGr1   info)rO   countpluralr   r   r   rL   $  s   rL   r?   c                 C   s   | du rt jdkrdS dS | S )zC
    see https://github.com/samuelcolvin/watchfiles/issues/110
    Nwin32i  r*   )sysplatform)r?   r   r   r   rV   .  s
   
rV   c                 C   s,   | dur| S t d}|r| dvS t S )z
    See docstring for `watch` above for details.

    See samuelcolvin/watchfiles#167 and samuelcolvin/watchfiles#187 for discussion and rationale.
    NWATCHFILES_FORCE_POLLING>   falsedisabledisabled)osgetenvlower_auto_force_polling)r3   env_varr   r   r   rD   ;  s   
rD   c                 C      | d ur| S t d}t|S )NWATCHFILES_DEBUGrw   rx   r(   )r1   r{   r   r   r   rF   J     
rF   c                  C   s,   ddl } |  }d|j v o|j dkS )z
    Whether to auto-enable force polling, it should be enabled automatically only on WSL.

    See samuelcolvin/watchfiles#187 for discussion.
    r   Nzmicrosoft-standardlinux)rr   unamereleasery   system)rr   r   r   r   r   rz   Q  s   rz   c                 C   r|   )N#WATCHFILES_IGNORE_PERMISSION_DENIEDr~   )r6   r{   r   r   r   rE   ]  r   rE   )-ri   rw   rq   rQ   enumr   pathlibr   typingr   r   r   r   r   r	   r
   r   rT   _rust_notifyr   filtersr   __all__	getLoggerrH   r   r$   r   asyncior%   triorU   rP   r&   r(   intr   r   rK   rL   rV   rD   rF   rz   rE   r   r   r   r   <module>   s    (

	

`
	

 	


