
    +DCf6                      P   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 j.                  d	      Z G d
 de      Zeeef   Z	 e	r?d dlZd dlmZ d dlZeej>                  ej>                  ej>                  f   Z  G 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"de"dee"   d e#d!e"d"ee"   d#eee   ddf   f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"dee"   dee"   d e#d!e"d"ee"   d#e
ee   df   fd&Z%d'eee#ef      deeeege"f      d#ee   fd(Z&d)ee   d#dfd*Z'd+ee#   d#e#fd,Z(dee"   d#e"fd-Z)d#e"fd.Z*d"ee"   d#e"fd/Z+y)0    N)IntEnum)Path)TYPE_CHECKINGAsyncGeneratorCallable	GeneratorOptionalSetTupleUnion   )
RustNotify)DefaultFilter)watchawatchChange
FileChangezwatchfiles.mainc                   .    e Zd ZdZdZ	 dZ	 dZ	 defdZy)r   z=
    Enum representing the type of change that occurred.
    r         returnc                     | j                   S N)nameselfs    O/var/www/highfloat_scraper/venv/lib/python3.12/site-packages/watchfiles/main.pyraw_strzChange.raw_str   s    yy    N)	__name__
__module____qualname____doc__addedmodifieddeletedstrr    r   r   r   r      s-     E,HTG* r   r   )Protocolc                       e Zd ZdefdZy)AbstractEventr   c                      y r   r(   r   s    r   is_setzAbstractEvent.is_set1   s    r   N)r    r!   r"   boolr-   r(   r   r   r+   r+   0   s    	D 	r   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pathsr1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r   c              '     K   t        |      }t        |      }t        |D cg c]  }t        |       c}|||	|
|      5 }	 |j	                  ||||      }|dk(  r%|rt                nt        j                  d       no|dk(  r'|rt        t        j                  d       	 ddd       y|dk(  r
	 ddd       yt        ||       }|rt        |       | nt        j                  d|       c c}w # 1 sw Y   yxY ww)aj  
    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 us 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.
        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)
    ```
    timeoutrust notify timeout, continuingsignalz(KeyboardInterrupt caught, stopping watchNstop(all changes filtered out, raw_changes=%s)_default_force_polling!_default_ignore_permission_deniedr   r'   r   setloggerr7   KeyboardInterruptwarning_prep_changes_log_changes)r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   pwatcherraw_changeschangess                    r   r   r   5   s    ~ +=9M@AYZ	AQ}iQi
 Z	!--$jQKi'#%KLL!BC("++NN#MNZ Z  &#Z Z& (\B )!MLL!K[Y+  	 Z Zs@    DC0D A#C5#	D,C52	D;5C50D5C>:DAnyEventc           	       K   |t        j                  dt               |t        j                         }n|}t        |      }t        |      }t        |D cg c]  }t        |       c}|||	|
|      5 }t        |      }t        j                         }	 t        j                         4 d{   }	 t        j                  j                  |j                  ||||       d{   }|j"                  j%                          ddd      d{    dk(  r&|rt!                njt&        j)                  d       nT|dk(  r
	 ddd       y|dk(  rt+        d      t-        ||       }|rt/        |       | nt&        j)                  d|       c c}w 7 7 # |t        f$ r |j!                           w xY w7 # 1 d{  7  sw Y   xY w# 1 sw Y   yxY ww)	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.r?   r@   rB   rA   z+watch thread unexpectedly received a signalrC   )warningswarnDeprecationWarninganyioEventrD   rE   r   r'   _calc_async_timeoutget_cancelled_exc_classcreate_task_group	to_threadrun_syncr   rH   rF   cancel_scopecancelrG   r7   RuntimeErrorrJ   rK   )r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   stop_event_rL   rM   r?   CancelledErrortgrN   rO   s                        r   r   r      s    l "o	
 "'++- *=9M@AYZ	AQ}iQi
  Z	%l3668..0 ) )B(-(@(@PXZ^`git(u"uK
 &&() ) i'#%KLL!BC&- Z  Z. ("#PQQ'\B )!MLL!K[Y5  	 )"u&(9: OO%) ) ) ) Z  Zs   AGF)G59G.F/G2F>40F$F%F)F>GF<5G	GAGGGFF99F><G>G	GG	GGGrN   c                     | D ch c]  \  }}t        |      |f }}}|r|D ch c]  } ||d   |d         s| }}|S c c}}w c c}w )Nr   r   )r   )rN   r1   changepathrO   cs         r   rJ   rJ     sZ     ;FF,&$v%FGF%BadAaD)A1BBN GBs   AA	A	rO   c                    t         j                  t        j                        rht	        |       }|dk(  rdnd}t         j                  t        j
                        rt         j                  d|||        y t         j                  d||       y y )Nr    sz%d change%s detected: %sz%d change%s detected)rG   isEnabledForloggingINFOlenDEBUGr7   info)rO   countplurals      r   rK   rK   "  se    7<<(Gzsw}}-LL3UFGLKK.v> )r   r?   c                 4    | t         j                  dk(  ryy| S )zC
    see https://github.com/samuelcolvin/watchfiles/issues/110
    win32i  r0   )sysplatform)r?   s    r   rW   rW   ,  s      <<7"r   c                 p    | | S t        j                  d      }|r|j                         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.
    WATCHFILES_FORCE_POLLING>   falsedisabledisabled)osgetenvlower_auto_force_polling)r9   env_vars     r   rD   rD   9  s=      ii23G}}&FFF"$$r   c                      ddl } | j                         }d|j                  j                         v xr |j                  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)rt   unamereleaser|   system)rt   r   s     r   r}   r}   H  sC     NNE5==#6#6#88\U\\=O=O=QU\=\\r   c                 J    | | S t        j                  d      }t        |      S )N#WATCHFILES_IGNORE_PERMISSION_DENIED)rz   r{   r.   )r<   r~   s     r   rE   rE   T  s'    +''ii=>G=r   ),rj   rz   rs   rR   enumr   pathlibr   typingr   r   r   r   r	   r
   r   r   rU   _rust_notifyr   filtersr   __all__	getLoggerrG   r   r'   r   asyncior)   triorV   rP   r+   r.   intr   r   rJ   rK   rW   rD   r}   rE   r(   r   r   <module>r      si    	 
    b b b  $ "
3			,	-W   63;

 U[['--;<H  ?Lo,0" $(/3YZ$)YZ8XsOT$9:;YZ YZ 	YZ
 )YZ YZ YZ YZ YZ D>YZ YZ YZ 'tnYZ s:d*+YZ| =JO'+"&"&*$(/3DZ$)DZ8VSM4$789DZ DZ 	DZ
 $DZ 3-DZ DZ DZ d^DZ D>DZ DZ DZ 'tnDZ C
OT)*DZNU38_%5=hPS}VZGZ>[5\_?#j/ ?d ?
# 
3 
%(4. %T %	]T 	] SW r   