ó
    &ÝNjŒ;  ã            !       ó,  • S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SKrS SK	J
r
Jr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJrJr  S SKrS	S
KJr  S	SKJrJrJrJ r   \(       a  S SKJ!r!  Sr"\RF                  " S5      r$SSSS\" 5       S SSSSS	SSS.S\\%-  S\%\
S\4   -  S\&\S4   S\'\%\4   S-  SSS\
\(\   /S4   S-  S\
\\%/\)4   S-  S \*S!\+S"\+S#\)S-  S$\+S%\+S&\)S'\)S(\+4 S) jjr,SSSS\" 5       S SSSSSS*.S\\%-  S\%\
S\4   -  S\&\S4   S\'\%\4   S-  SSS\
\(\   /\4   S-  S\
\\%/\)4   S-  S \*S!\+S"\+S#\)S-  S&\)S'\)S(\+4S+ jjr-\" S,5      r.S-\%S(\/\%   4S. jr0 SAS\%\
S\4   -  SS/S\&\S4   S\'\%\4   S-  S0\(\   S-  S(S14S2 jjr1S\%\
S\4   -  S(S/4S3 jr2 " S4 S15      r3S5\%S6\%S-  S\&\S4   S\'\%\4   S(S4
S7 jr4S8\%S(\4S9 jr5S(\%S-  4S: jr6\ Rn                  S6\%S-  S(\S;   4S< j5       r8S=\+S>\S(S4S? jr9SBS@ jr:g)Cé    N)ÚCallableÚ	Generator)Úimport_module)Úget_context)ÚSpawnProcess)ÚPath)Úsleep)ÚTYPE_CHECKINGÚAnyé   )ÚDefaultFilter)ÚChangeÚ
FileChangeÚawatchÚwatch)ÚLiteral)Úrun_processÚarun_processÚdetect_target_typeÚimport_stringzwatchfiles.main© Úautoi@  é2   é   TF)ÚargsÚkwargsÚtarget_typeÚcallbackÚwatch_filterÚgrace_periodÚdebounceÚstepÚdebugÚsigint_timeoutÚsigkill_timeoutÚ	recursiveÚignore_permission_deniedÚpathsÚtarget.r   r   r   z&Literal['function', 'command', 'auto']r   r   r    r!   r"   r#   r$   r%   r&   r'   Úreturnc                 ó´  • US:X  a  [        U 5      n[        R                  SX5        [        5         [	        XX5      nSnU(       a!  [        R                  SU5        [        U5         [        UUUUU	SUUS.6 H5  nU=(       a    U" U5        UR                  X«S9  [	        XXU5      nUS-  nM7     UR                  5         U$ ! UR                  5         f = f)	uš  
Run a process and restart it upon file changes.

`run_process` can work in two ways:

* Using `multiprocessing.Process` â€  to run a python function
* Or, using `subprocess.Popen` to run a command

!!! note

    **â€ ** technically `multiprocessing.get_context('spawn').Process` to avoid forking and improve
    code reload/import.

Internally, `run_process` uses [`watch`][watchfiles.watch] with `raise_interrupt=False` so the function
exits cleanly upon `Ctrl+C`.

Args:
    *paths: matches the same argument of [`watch`][watchfiles.watch]
    target: function or command to run
    args: arguments to pass to `target`, only used if `target` is a function
    kwargs: keyword arguments to pass to `target`, only used if `target` is a function
    target_type: type of target. Can be `'function'`, `'command'`, or `'auto'` in which case
        [`detect_target_type`][watchfiles.run.detect_target_type] is used to determine the type.
    callback: function to call on each reload, the function should accept a set of changes as the sole argument
    watch_filter: matches the same argument of [`watch`][watchfiles.watch]
    grace_period: number of seconds after the process is started before watching for changes
    debounce: matches the same argument of [`watch`][watchfiles.watch]
    step: matches the same argument of [`watch`][watchfiles.watch]
    debug: matches the same argument of [`watch`][watchfiles.watch]
    sigint_timeout: the number of seconds to wait after sending sigint before sending sigkill
    sigkill_timeout: the number of seconds to wait after sending sigkill before raising an exception
    recursive: matches the same argument of [`watch`][watchfiles.watch]

Returns:
    number of times the function was reloaded.

```py title="Example of run_process running a function"
from watchfiles import run_process

def callback(changes):
    print('changes detected:', changes)

def foobar(a, b):
    print('foobar called with:', a, b)

if __name__ == '__main__':
    run_process('./path/to/dir', target=foobar, args=(1, 2), callback=callback)
```

As well as using a `callback` function, changes can be accessed from within the target function,
using the `WATCHFILES_CHANGES` environment variable.

```py title="Example of run_process accessing changes"
from watchfiles import run_process

def foobar(a, b, c):
    # changes will be an empty list "[]" the first time the function is called
    changes = os.getenv('WATCHFILES_CHANGES')
    changes = json.loads(changes)
    print('foobar called due to changes:', changes)

if __name__ == '__main__':
    run_process('./path/to/dir', target=foobar, args=(1, 2, 3))
```

Again with the target as `command`, `WATCHFILES_CHANGES` can be used
to access changes.

```bash title="example.sh"
echo "changers: ${WATCHFILES_CHANGES}"
```

```py title="Example of run_process running a command"
from watchfiles import run_process

if __name__ == '__main__':
    run_process('.', target='./example.sh')
```
r   úrunning "%s" as %sr   ú3sleeping for %s seconds before watching for changesF)r   r!   r"   r#   Úraise_interruptr&   r'   )r$   r%   r   )r   Úloggerr#   Úcatch_sigtermÚstart_processr	   r   Ústop)r)   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   ÚprocessÚreloadsÚchangess                     ÚK/home/mande/repo/quber/.venv/lib/python3.13/site-packages/watchfiles/run.pyr   r      sÔ   € ð@ �fÓÜ(¨Ó0ˆä
‡L�LÐ% vÔ;Ü„OÜ˜F°Ó>€GØ€GæÜ�‰ÐJÈLÔYÜˆlÔðÜØØ%ØØØØ!ØØ%=õ	
ˆGð ×*™ 'Ó*øØ�L‰L¨ˆLÑXÜ# F¸ÀwÓOˆGØ�q‰LŠGñ	
ð 	�‰ŒØ€Nøð 	�‰�ús   Á)A
C ÃC)r   r   r   r   r   r    r!   r"   r#   r&   r'   c           
   ‡   ó  #   • SSK nUS:X  a  [        U 5      n[        R                  SX5        [	        5         [
        R                  R                  [        XX5      I Sh  v•N nSnU(       a4  [        R                  SU5        [
        R                  " U5      I Sh  v•N   [        UUUUU	U
US.6  Sh  v•N nUb(  U" U5      nUR                  U5      (       a
  UI Sh  v•N   [
        R                  R                  UR                  5      I Sh  v•N   [
        R                  R                  [        XXU5      I Sh  v•N nUS-  nMš   Në N° N™ Np NA N
 [
        R                  R                  UR                  5      I Sh  v•N    U$ 7f)a³  
Async equivalent of [`run_process`][watchfiles.run_process], all arguments match those of `run_process` except
`callback` which can be a coroutine.

Starting and stopping the process and watching for changes is done in a separate thread.

As with `run_process`, internally `arun_process` uses [`awatch`][watchfiles.awatch], however `KeyboardInterrupt`
cannot be caught and suppressed in `awatch` so these errors need to be caught separately, see below.

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

async def callback(changes):
    await asyncio.sleep(0.1)
    print('changes detected:', changes)

def foobar(a, b):
    print('foobar called with:', a, b)

async def main():
    await arun_process('.', target=foobar, args=(1, 2), callback=callback)

if __name__ == '__main__':
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print('stopped via KeyboardInterrupt')
```
r   Nr   r,   r-   )r   r!   r"   r#   r&   r'   r   )Úinspectr   r/   r#   r0   ÚanyioÚ	to_threadÚrun_syncr1   r	   r   Úisawaitabler2   )r)   r   r   r   r   r   r    r!   r"   r#   r&   r'   r(   r8   r3   r4   r5   Úrs                     r6   r   r   ž   sK  é € óZ à�fÓÜ(¨Ó0ˆä
‡L�LÐ% vÔ;Ü„OÜ—O‘O×,Ñ,¬]¸FÐQUÓ^×^€GØ€GæÜ�‰ÐJÈLÔYÜ�kŠk˜,Ó'×'Ð'äØ	Ø!ØØØØØ!9ó÷ ˆgð ÑÙ˜Ó!ˆAØ×"Ñ" 1×%Ñ%Ø—�ä�o‰o×&Ñ& w§|¡|Ó4×4Ð4ÜŸ™×0Ñ0´ÀÐUYÐcjÓk×kˆØ�1‰Šñ/ _ñ
 	(ññ á4Ùkðô" �/‰/×
"Ñ
" 7§<¡<Ó
0×0Ñ0Ø€NùsŠ   ‚AFÁ EÁ!<FÂEÂFÂ2EÂ6EÂ7EÂ:'FÃ!EÃ"0FÄEÄ-FÅ EÅFÅFÅEÅFÅFÅFÅ-FÆFÆFÚspawnÚcmdc                 óˆ   • SS K nUR                  5       R                  R                  5       S:g  n[        R
                  " XS9$ )Nr   Úwindows)Úposix)ÚplatformÚunameÚsystemÚlowerÚshlexÚsplit)r?   rC   rB   s      r6   Ú	split_cmdrI   ó   s4   € Ûà�N‰NÓ×#Ñ#×)Ñ)Ó+¨yÑ8€EÜ�;Š;�sÑ(Ð(ó    zLiteral['function', 'command']r5   ÚCombinedProcessc                 óR  • Uc  SnO;[         R                  " U VVs/ s H  u  pgUR                  5       U/PM     snn5      nU[        R                  S'   US:X  a]  U=(       d    0 n[        U [        5      (       a  U [        5       X#4n[        n0 nOU n[        R                  X‚US9n	U	R                  5         O`U(       d  U(       a  [        R                  S5        [        U [        5      (       d   S5       e[        U 5      n
[        R                   " U
5      n	[#        U	5      $ s  snnf )Nz[]ÚWATCHFILES_CHANGESÚfunction)r)   r   r   z-ignoring args and kwargs for "command" targetz+target must be a string to run as a command)ÚjsonÚdumpsÚraw_strÚosÚenvironÚ
isinstanceÚstrÚget_tty_pathÚrun_functionÚspawn_contextÚProcessÚstartr/   ÚwarningrI   Ú
subprocessÚPopenrK   )r)   r   r   r   r5   Úchanges_env_varÚcÚpÚtarget_r3   Ú
popen_argss              r6   r1   r1   ú   sø   € ð �Ø‰äŸ*š*Á7Ô%KÂ7¹4¸1 q§y¡y£{°AÓ&6Á7Ò%KÓLˆà'6„B‡J�JÐ#Ñ$ð �jÓ Ø—˜2ˆÜ�fœc×"Ñ"Øœ<›>¨4Ð7ˆDÜ"ˆGØ‰FàˆGä×'Ñ'¨wÈ&Ð'ÐQˆØ�‰�æ–6Ü�N‰NÐJÔKä˜&¤#×&Ñ&ÐUÐ(UÓUÐ&Ü˜vÓ&ˆ
Ü×"Ò" :Ó.ˆÜ˜7Ó#Ð#ùó/ &Ls   œD#
c                 ó˜   • [        U [        5      (       d  gU R                  S5      (       a  g[        R                  " SU 5      (       a  gg)a&  
Used by [`run_process`][watchfiles.run_process], [`arun_process`][watchfiles.arun_process]
and indirectly the CLI to determine the target type with `target_type` is `auto`.

Detects the target type - either `function` or `command`. This method is only called with `target_type='auto'`.

The following logic is employed:

* If `target` is not a string, it is assumed to be a function
* If `target` ends with `.py` or `.sh`, it is assumed to be a command
* Otherwise, the target is assumed to be a function if it matches the regex `[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)+`

If this logic does not work for you, specify the target type explicitly using the `target_type` function argument
or `--target-type` command line argument.

Args:
    target: The target value

Returns:
    either `'function'` or `'command'`
rN   )z.pyz.shÚcommandz[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)+)rT   rU   ÚendswithÚreÚ	fullmatch)r)   s    r6   r   r     s>   € ô, �fœc×"Ñ"ØØ	�‰˜×	(Ñ	(ØÜ	�ŠÐ8¸&×	AÑ	AØàrJ   c                   óŽ   • \ rS rSrSS jrSS\S\SS4S jjrS\4S jr\	S\4S	 j5       r
S
\SS4S jr\	S\S-  4S j5       rSrg)rK   i>  c                 ó8   • Xl         U R                  c   S5       eg )Nzprocess not yet spawned©Ú_pÚpid)Úselfr`   s     r6   Ú__init__ÚCombinedProcess.__init__?  s   € ØŒØ�x‰xÑ#Ð>Ð%>Ó>Ñ#rJ   r$   r%   r*   Nc                 ó¬  • [         R                  R                  SS 5        U R                  5       (       aÏ  [        R                  S5        [         R                  " U R                  [        R                  5         U R                  U5        U R                  cV  [        R                  S5        [         R                  " U R                  [        R                  5        U R                  U5        g [        R                  S5        g [        R                  SU R                  5        g ! [        R                   a    [        R                  SU5         NÆf = f)NrM   zstopping process...z!SIGINT timed out after %r secondsz+process has not terminated, sending SIGKILLzprocess stoppedz#process already dead, exit code: %d)rR   rS   ÚpopÚis_aliver/   r#   Úkillrl   ÚsignalÚSIGINTÚjoinr\   ÚTimeoutExpiredr[   ÚexitcodeÚSIGKILL)rm   r$   r%   s      r6   r2   ÚCombinedProcess.stopC  sÚ   € Ü
�
‰
�‰Ð+¨TÔ2Ø�=‰=�?‰?Ü�L‰LÐ.Ô/ä�GŠG�D—H‘HœfŸm™mÔ,ðØ—	‘	˜.Ô)ð �}‰}Ñ$Ü—‘ÐLÔMÜ—’˜Ÿ™¤&§.¡.Ô1Ø—	‘	˜/Õ*ä—‘Ð.Õ/ä�N‰NÐ@À$Ç-Á-ÕPøô ×,Ñ,ó ô —‘ÐBÀNÔSÙð	ús   Á;D& Ä&*EÅEc                 ó¬   • [        U R                  [        5      (       a  U R                  R                  5       $ U R                  R	                  5       S L $ ©N)rT   rk   r   rr   Úpoll©rm   s    r6   rr   ÚCombinedProcess.is_alive[  s;   € Ü�d—g‘gœ|×,Ñ,Ø—7‘7×#Ñ#Ó%Ð%à—7‘7—<‘<“> TÐ)Ð)rJ   c                 ó.   • U R                   R                  $ r|   rj   r~   s    r6   rl   ÚCombinedProcess.pida  s   € ð �w‰w�{‰{ÐrJ   Útimeoutc                 ó°   • [        U R                  [        5      (       a  U R                  R                  U5        g U R                  R	                  U5        g r|   )rT   rk   r   rv   Úwait)rm   r‚   s     r6   rv   ÚCombinedProcess.joinf  s3   € Ü�d—g‘gœ|×,Ñ,Ø�G‰G�L‰L˜Õ!à�G‰G�L‰L˜Õ!rJ   c                 ó˜   • [        U R                  [        5      (       a  U R                  R                  $ U R                  R                  $ r|   )rT   rk   r   rx   Ú
returncoder~   s    r6   rx   ÚCombinedProcess.exitcodel  s3   € ä�d—g‘gœ|×,Ñ,Ø—7‘7×#Ñ#Ð#à—7‘7×%Ñ%Ð%rJ   )rk   )r`   z&SpawnProcess | subprocess.Popen[bytes])r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__rn   Úintr2   Úboolrr   Úpropertyrl   rv   rx   Ú__static_attributes__r   rJ   r6   rK   rK   >  s~   † ô?ñQ 3ð Q¸Sð QÈõ Qð0*˜$ô *ð ð�Só ó ðð"˜Cð " Dô "ð ð&˜# ™*ó &ó ó&rJ   rN   Útty_pathc                 ót   • [        U5         [        U 5      nU" U0 UD6  S S S 5        g ! , (       d  f       g = fr|   )Úset_ttyr   )rN   r‘   r   r   Úfuncs        r6   rW   rW   t  s-   € Ü	�Õ	Ü˜XÓ&ˆÙˆdÐ�fÒ÷ 
×	Ö	ús   Œ)©
7Údotted_pathc                 ó  •  U R                  S5      R                  SS5      u  p[	        U5      n [        XB5      $ ! [         a  n[        SU  S35      UeSnAff = f! [         a  n[        SU SU S	35      UeSnAff = f)
z®
Stolen approximately from django. Import a dotted module path and return the attribute/class designated by the
last name in the path. Raise ImportError if the import fails.
Ú Ú.r   Ú"z!" doesn't look like a module pathNzModule "z" does not define a "z" attribute)ÚstripÚrsplitÚ
ValueErrorÚImportErrorr   ÚgetattrÚAttributeError)r•   Úmodule_pathÚ
class_nameÚeÚmodules        r6   r   r   z  s£   € ð
VØ"-×"3Ñ"3°CÓ"8×"?Ñ"?ÀÀQÓ"GÑˆô ˜;Ó'€FðgÜ�vÓ*Ð*øô ó VÜ˜A˜k˜]Ð*LÐMÓNÐTUÐUûðVûô ó gÜ˜H [ MÐ1FÀzÀlÐR]Ð^Ó_ÐefÐfûðgús,   ‚#< ±
A ¼
AÁAÁAÁ
B Á(A;Á;B c                  óž   •  [         R                  " [        R                  R	                  5       5      $ ! [
         a     g[         a     gf = f)zf
Return the path to the current TTY, if any.

Virtually impossible to test in pytest, hence no cover.
z/dev/ttyN)rR   ÚttynameÚsysÚstdinÚfilenoÚOSErrorrŸ   r   rJ   r6   rV   rV   ‹  s@   € ðÜ�zŠzœ#Ÿ)™)×*Ñ*Ó,Ó-Ð-øÜó áÜó áðús   ‚14 ´
AÁ 	AÁA)NNNc              #   ó¶   #   • U (       a%   [        U 5       nU[        l        S v •  S S S 5        g S v •  g ! , (       d  f       g = f! [         a    S v •   g f = f7fr|   )Úopenr¦   r§   r©   )r‘   Úttys     r6   r“   r“   ›  sF   é € æð	Ü�h” 3Ø””	Û÷  �ô 	÷  •ûô ó 	åð	üsF   ‚A‹A –4¦A ®A´
A¾A ÁAÁA ÁAÁAÁAÁAÚsignumÚ_framec                 ób   • [         R                  S[        R                  " U 5      5        [        e)Nz-received signal %s, raising KeyboardInterrupt)r/   r[   rt   ÚSignalsÚKeyboardInterrupt)r­   r®   s     r6   Úraise_keyboard_interruptr²   ª  s!   € Ü
‡N�NÐBÄFÇNÂNÐSYÓDZÔ[Ü
ÐrJ   c                  ó¨   • [         R                  S[        R                  " 5       5        [        R                  " [        R
                  [        5        g)a  
Catch SIGTERM and raise KeyboardInterrupt instead. This means watchfiles will stop quickly
on `docker compose stop` and other cases where SIGTERM is sent.

Without this the watchfiles process will be killed while a running process will continue uninterrupted.
z8registering handler for SIGTERM on watchfiles process %dN)r/   r#   rR   Úgetpidrt   ÚSIGTERMr²   r   rJ   r6   r0   r0   ¯  s,   € ô ‡L�LÐKÌRÏYÊYË[ÔYÜ
‡M‚M”&—.‘.Ô":Õ;rJ   r|   )r*   N);Ú
contextlibrO   ÚloggingrR   rf   rG   rt   r\   r¦   Úcollections.abcr   r   Ú	importlibr   Úmultiprocessingr   Úmultiprocessing.contextr   Úpathlibr   Útimer	   Útypingr
   r   r9   Úfiltersr   Úmainr   r   r   r   r   Ú__all__Ú	getLoggerr/   rU   ÚtupleÚdictÚsetrŽ   Úfloatr�   r   r   rX   ÚlistrI   r1   r   rK   rW   r   rV   Úcontextmanagerr“   r²   r0   r   rJ   r6   Ú<module>rÉ      s  ðÛ Û Û Û 	Û 	Û Û Û Û 
ß /Ý #Ý 'Ý 0Ý Ý ß %ã å "ß 3Ó 3æÝà
N€Ø	×	Ò	Ð,Ó	-€ð Ø$(Ø<BØ9=Ù9F»ØØØØØØØØ%*ò}Ø�3‰Jð}à�(˜3 ˜8Ñ$Ñ$ð}ð ��S�‰/ð}ð ��c�‰N˜TÑ!ð	}ð
 :ð}ð ˜˜J™Ð(¨$Ð.Ñ/°$Ñ6ð}ð ˜F C˜=¨$Ð.Ñ/°$Ñ6ð}ð ð}ð ð}ð ð}ð �$‰;ð}ð ð}ð ð}ð ð}ð #ð}ð  	õ!}ðF Ø$(Ø<BØ8<Ù9F»ØØØØØØ%*òMØ�3‰JðMà�(˜3 ˜8Ñ$Ñ$ðMð ��S�‰/ðMð ��c�‰N˜TÑ!ð	Mð
 :ðMð ˜˜J™Ð(¨#Ð-Ñ.°Ñ5ðMð ˜F C˜=¨$Ð.Ñ/°$Ñ6ðMð ðMð ðMð ðMð �$‰;ðMð ðMð #ðMð 	õMñd ˜GÓ$€ð)�3ð )˜4 ™9ô )ð '+ñ!$Ø�(˜3 ˜8Ñ$Ñ$ð!$à1ð!$ð ��S�‰/ð!$ð ��c�‰N˜TÑ!ð	!$ð
 �‰_˜tÑ#ð!$ð õ!$ðH˜s X¨c°3¨hÑ%7Ñ7ð Ð<\ô ÷@3&ñ 3&ðl˜3ð ¨#°©*ð ¸EÀ#ÀsÀ(¹Oð ÐUYÐZ]Ð_bÐZbÑUcð Ðhlô ðg˜sð g sô gð"�c˜D‘jô ð  ×Ñð�c˜D‘jð  YÐ/?Ñ%@ó ó ðð Sð °#ð ¸$ô õ
<rJ   