
    \jx                    *   U d Z ddlm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	Z	ddl
Z
ddlZddlZddlZddlmZmZ ddlmZ ddlmZ ddlmZm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! erddl"m#Z#m$Z$ ed   Z%dZ&dZ' e(edd      Z)e
jT                  dk7  xr ejV                  ejX                  v Z- e       Z.de/d<    ej`                         a1da2da3 ed       G d d             Z4e G d d             Z5 ed       G d d             Z6e G d d             Z7 G d  d!e8      Z9 G d" d#e9$      Z: G d% d&ejv                        Z<dd'd3d(Z=dd'd4d)Z>d5d*Z?dd'	 	 	 	 	 	 	 	 	 d6d+Z@dd'd7d,ZAdd'd7d-ZBd8d.ZCd9d/ZDd:d0ZEd:d1ZFd:d2ZGd#gZHy);zZCross-process and cross-host reader/writer lock built on :class:`SoftFileLock` primitives.    )annotationsN)contextmanagersuppress)	dataclass)Path)TYPE_CHECKINGLiteral)WeakValueDictionary)AcquireReturnProxy)Timeout)SoftFileLock)ensure_directory_exists)Callable	Generator)readwritez.breaki   
O_NOFOLLOWwin32,WeakValueDictionary[Path, SoftReadWriteLock]_all_instancesFT)frozenc                  ,    e Zd ZU ded<   ded<   ded<   y)_Pathsstrstater   readersN__name__
__module____qualname____annotations__     A/root/env/lib/python3.12/site-packages/filelock/_soft_rw/_sync.pyr   r   -   s    JJLr#   r   c                  ,    e Zd ZU ded<   ded<   ded<   y)_Locksthreading.Lockinternaltransactionr   r   Nr   r"   r#   r$   r&   r&   4   s    r#   r&   c                  ,    e Zd ZU ded<   ded<   ded<   y)_MarkerInfor   tokenintpidhostnameNr   r"   r#   r$   r+   r+   ;   s    J	HMr#   r+   c                  b    e Zd ZU dZded<   ded<   ded<   ded	<   d
ed<   ded<   ded<   ded<   y)_HoldzYEverything that exists only while a lock is held; ``None`` when the instance has no lock.r-   level_Modemode
int | Nonewrite_thread_idr   marker_namebool	is_readerr,   _HeartbeatThreadheartbeat_threadthreading.Eventheartbeat_stopN)r   r   r    __doc__r!   r"   r#   r$   r1   r1   B   s1    cJ
KOJ&&##r#   r1   c                  f     e Zd ZU ded<   ded<   	 ddddddd		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fd
Z xZS )_SoftRWMetar   
_instancesr'   _instances_lockT      >@N      ?blockingis_singletonheartbeat_intervalstale_thresholdpoll_intervalc          
        |st         |   |||||||      S t        |      j                         }| j                  5  | j
                  j                  |      }	|	&t         |   |||||||      }	|	| j
                  |<   nK|	j                  |k7  s|	j                  |k7  r-d|	j                   d|	j                   d| d| }
t        |
      |	cd d d        S # 1 sw Y   y xY w)NrE   z$Singleton lock created with timeout=z, blocking=z, cannot be changed to timeout=)
super__call__r   resolverB   rA   gettimeoutrF   
ValueError)cls	lock_filerP   rF   rG   rH   rI   rJ   
normalizedinstancemsg	__class__s              r$   rM   z_SoftRWMeta.__call__T   s    7#!)#5 /+ $   )_,,.
   	~~))*5H 7+%!-'9$3"/ ,  .6z*!!W,0A0AX0M:8;K;K:LKX`XiXiWj k55<I[
T  !o%'	 	 	s   BCC")rS   str | os.PathLike[str]rP   floatrF   r8   rG   r8   rH   r[   rI   float | NonerJ   r[   returnSoftReadWriteLock)r   r   r    r!   rM   __classcell__rW   s   @r$   r@   r@   P   s    <<##
 *
 !$((,#*)* *
 * * "* &* * 
* *r#   r@   c                     e Zd ZU dZ e       Zded<    ej                         Z		 ddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d d	Z
ed!dd
d"d       Zed!dd
d"d       Zd!dd
d#dZd!dd
d#dZd$dZddd%dZe	 ddd
	 	 	 	 	 	 	 d&d       Z	 	 	 	 	 	 	 	 d'dZd(dZ	 	 	 	 	 	 	 	 d)dZ	 	 	 	 	 	 	 	 d)dZ	 	 	 	 	 	 	 	 d*dZd$dZd+dZd,dZd-dZd+dZd$dZy).r^   u
  
    Cross-process and cross-host reader/writer lock built on :class:`SoftFileLock` primitives.

    Use this class instead of :class:`~filelock.ReadWriteLock` when the lock file lives on a network
    filesystem (NFS, Lustre with ``-o flock``, HPC cluster shared storage). ``ReadWriteLock`` is backed
    by SQLite and cannot run on NFS because SQLite's ``fcntl`` locking is unreliable there.

    Layout on disk for a lock at ``foo.lock``:

    - ``foo.lock.state`` — a :class:`SoftFileLock` taken only during state transitions (microseconds).
    - ``foo.lock.write`` — writer marker; its presence means a writer is claiming or holding the lock.
    - ``foo.lock.readers/<host>.<pid>.<uuid>`` — one file per reader.

    Each marker stores a random token (``secrets.token_hex(16)``), the holder's pid, and the holder's
    hostname. A daemon heartbeat thread refreshes ``mtime`` on every held marker. A marker whose mtime
    has not advanced in ``stale_threshold`` seconds may be evicted by any process on any host, giving
    correct behavior when a compute node crashes with a lock held.

    Writer acquire is two-phase and writer-preferring: phase 1 claims ``.write`` (blocking any new
    reader), phase 2 waits for existing readers to drain. Writer starvation is impossible.

    Reentrancy, upgrade/downgrade rules, thread pinning, and singleton caching by resolved path match
    :class:`~filelock.ReadWriteLock`.

    Forking while holding a lock invalidates the inherited instance in the child so the child cannot
    double-own the lock with its parent; ``release()`` on a fork-invalidated instance is a no-op, and
    the child must re-acquire if it needs a lock.

    Trust boundary: protects against same-UID non-cooperating processes (one host or cross-host) and
    same-host different-UID users via ``0o600`` / ``0o700`` permissions. Does not protect against root
    compromise, NTP tampering on same-UID cross-host nodes, or multi-tenant mounts where hostile
    co-tenants share the UID.

    :param lock_file: path to the lock file; sidecar state/write/readers live next to it
    :param timeout: maximum wait time in seconds; ``-1`` means block indefinitely
    :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately on contention
    :param is_singleton: if ``True``, reuse existing instances for the same resolved path
    :param heartbeat_interval: seconds between heartbeat refreshes; default 30 s
    :param stale_threshold: seconds of ``mtime`` inactivity before a marker is stale; defaults to
        ``3 * heartbeat_interval``, matching etcd's ``LeaseKeepAlive`` convention
    :param poll_interval: seconds between acquire retries under contention; default 0.25 s

    .. versionadded:: 3.27.0

    r   rA   TrC   NrD   rE   c               2   |dk  rd| }t        |      ||dz  }||k  rd| d| d}t        |      |dk  rd| }t        |      t        j                  |      | _        || _        || _        || _        || _        || _        t        | j                   d| j                   d	| j                   d
      | _
        t        | j                         t        t        j                         t        j                         t        | j                  j                   d            | _        d | _        d | _        d| _        d| _        t,        5  | t.        t1        | j                        j3                         <   t5                d d d        y # 1 sw Y   y xY w)Nr   z)heartbeat_interval must be positive, got    z0stale_threshold must exceed heartbeat_interval (z <= )z$poll_interval must be positive, got z.statez.writez.readers)r   r   r   rY   rP   r(   r)   r   F)rQ   osfspathrS   rP   rF   rH   rI   rJ   r   _pathsr   r&   	threadingLockr   r   _locks_readers_dir_fd_hold_fork_invalidated_closed_all_instances_lockr   r   rN   _register_hooks)	selfrS   rP   rF   rG   rH   rI   rJ   rV   s	            r$   __init__zSoftReadWriteLock.__init__   s    "=>P=QRCS/!"014O00D_DUUYZlYmmnoCS/!A8HCS/! ii	2%&);&5$1^^$F+^^$F+~~&h/

 	 /^^%!(t{{00"=

 ,0#'
',"  	=AN4/779:	 	 	s   5FFrF   c             #     K   | j                  ||       	 d | j                          y# | j                          w xY ww)a  
        Context manager that acquires and releases a shared read lock.

        Falls back to instance defaults for *timeout* and *blocking* when ``None``.

        :param timeout: maximum wait time in seconds, or ``None`` to use the instance default
        :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately; ``None`` uses the instance default

        :raises RuntimeError: if a write lock is already held on this instance
        :raises Timeout: if the lock cannot be acquired within *timeout* seconds

        ru   N)acquire_readreleasers   rP   rF   s      r$   	read_lockzSoftReadWriteLock.read_lock   s5      	'H5	LLNDLLN   A, A>Ac             #     K   | j                  ||       	 d | j                          y# | j                          w xY ww)a@  
        Context manager that acquires and releases an exclusive write lock.

        Falls back to instance defaults for *timeout* and *blocking* when ``None``.

        :param timeout: maximum wait time in seconds, or ``None`` to use the instance default
        :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately; ``None`` uses the instance default

        :raises RuntimeError: if a read lock is already held, or a write lock is held by a different thread
        :raises Timeout: if the lock cannot be acquired within *timeout* seconds

        ru   N)acquire_writerx   ry   s      r$   
write_lockzSoftReadWriteLock.write_lock   s5      	7X6	LLNDLLNr{   c               *    | j                  d||      S )uf  
        Acquire a shared read lock.

        If this instance already holds a read lock, the lock level is incremented (reentrant). Attempting to acquire a
        read lock while holding a write lock raises :class:`RuntimeError` (downgrade not allowed). On the 0→1
        transition a daemon heartbeat thread is started that refreshes the reader marker's ``mtime`` every
        ``heartbeat_interval`` seconds so peers on other hosts do not evict the marker as stale.

        :param timeout: maximum wait time in seconds, or ``None`` to use the instance default; ``-1`` means block
            indefinitely
        :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately when the lock is unavailable;
            ``None`` uses the instance default

        :returns: a proxy that can be used as a context manager to release the lock

        :raises RuntimeError: if a write lock is already held on this instance, if this instance was invalidated by
            :func:`os.fork`, or if :meth:`close` was called
        :raises Timeout: if the lock cannot be acquired within *timeout* seconds

        r   ru   _acquirery   s      r$   rw   zSoftReadWriteLock.acquire_read  s    * }}VWx}@@r#   c               *    | j                  d||      S )a  
        Acquire an exclusive write lock.

        If this instance already holds a write lock from the same thread, the lock level is incremented (reentrant).
        Attempting to acquire a write lock while holding a read lock raises :class:`RuntimeError` (upgrade not
        allowed). Write locks are pinned to the acquiring thread: a different thread trying to re-enter also raises
        :class:`RuntimeError`.

        Writer acquisition runs in two phases. Phase 1 atomically claims ``<path>.write`` via ``O_CREAT | O_EXCL``,
        which immediately blocks any new reader on any host. Phase 2 waits for existing readers to drain. Writer
        starvation is impossible: new readers see ``<path>.write`` during phase 2 and wait behind the pending writer.

        :param timeout: maximum wait time in seconds, or ``None`` to use the instance default; ``-1`` means block
            indefinitely
        :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately when the lock is unavailable;
            ``None`` uses the instance default

        :returns: a proxy that can be used as a context manager to release the lock

        :raises RuntimeError: if a read lock is already held, if a write lock is held by a different thread, if this
            instance was invalidated by :func:`os.fork`, or if :meth:`close` was called
        :raises Timeout: if the lock cannot be acquired within *timeout* seconds

        r   ru   r   ry   s      r$   r}   zSoftReadWriteLock.acquire_write$  s    2 }}Wg}AAr#   c                d   | j                  d       | j                  j                  5  | j                  r
	 ddd       yd| _        | j                  >t        t              5  t        j                  | j                         ddd       d| _        ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w)u  
        Release any held lock and release internal filesystem resources.

        Idempotent. After calling this method the instance can no longer acquire locks — subsequent acquires raise
        :class:`RuntimeError`. A fork-invalidated instance is closed without raising.
        TforceN)	rx   rl   r(   rp   rm   r   OSErrorrg   closers   s    r$   r   zSoftReadWriteLock.close?  s     	4 [[!! 	,||	, 	,  DL##/g& 3HHT1123'+$	, 	,
3 3	, 	,s)   B& "B&" BB&B#	B&&B/Fr   c                  | j                   j                  5  | j                  rd| _        	 ddd       y| j                  }|3|r
	 ddd       yd| j                   dt        |        d}t        |      |rd|_        n|xj                  dz  c_        |j                  dkD  r
	 ddd       yd| _        ddd       j                  j                          |j                  j                  | j                  dz          |j                  r"t        |j                  | j                   	       yt        |j                         y# 1 sw Y   xY w)
a8  
        Release one level of the current lock.

        When the lock level reaches zero the heartbeat thread is stopped and the held marker file is unlinked. On a
        fork-invalidated instance (that is, the child of a :func:`os.fork` call made while the parent held a lock)
        this method is a no-op so inherited ``with`` blocks can unwind cleanly in the child.

        :param force: if ``True``, release the lock completely regardless of the current lock level

        :raises RuntimeError: if no lock is currently held and *force* is ``False``

        NzCannot release a lock on  (lock id: z) that is not heldr      g      ?re   dir_fd)rl   r(   ro   rn   rS   idRuntimeErrorr2   r=   setr;   joinrH   r9   _unlinkr7   rm   )rs   r   holdrV   s       r$   rx   zSoftReadWriteLock.releaseP  s(    [[!! 	%%!
		 	
 ::D|	 	 2$..1ARPTXJVhi"3''


a
zzA~!	 	" DJ#	, 	!""4+B+BS+H"I>>D$$T-A-ABD$$%7	 	s   EEAE.EEc                    | |||      S )a  
        Return the singleton :class:`SoftReadWriteLock` for *lock_file*.

        :param lock_file: path to the lock file; sidecar state/write/readers live next to it
        :param timeout: maximum wait time in seconds; ``-1`` means block indefinitely
        :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately when the lock is unavailable

        :returns: the singleton lock instance

        :raises ValueError: if an instance already exists for this path with different *timeout* or *blocking* values

        ru   r"   )rR   rS   rP   rF   s       r$   get_lockzSoftReadWriteLock.get_lockz  s    ( 9g99r#   c                  || j                   n|}|| j                  n|}| j                  j                  5  | j                  rd| j
                   d}t        |      | j                  rd| j
                   d}t        |      | j                  | j                  |      cd d d        S 	 d d d        t        j                         }|s'| j                  j                  j                  d      }nS|dk(  r'| j                  j                  j                  d      }n'| j                  j                  j                  d|      }|st        | j
                        d 	 | j                  j                  5  | j                  >| j                  |      cd d d        | j                  j                  j                          S 	 d d d        |dk(  rd n||z   }	t!        j"                  d	      }
|d
k(  r| j%                  |
|	|      \  }}n| j'                  |
|	|      \  }}t)        j*                         }t-        | j.                  | j0                  |dt3        |       d      }| j                  j                  5  t5        d||d
k(  rt)        j6                         nd |||
||      | _        d d d        |j9                          t;        |       | j                  j                  j                          S # 1 sw Y   FxY w# 1 sw Y   @xY w# 1 sw Y   cxY w# | j                  j                  j                          w xY w)NzSoftReadWriteLock on z4 was invalidated by fork(); construct a new instancez has been closedFru   rY   T)rF   rP      r   deadlinerF   zfilelock-heartbeat-x)refreshinterval
stop_eventnamer   )r2   r4   r6   r7   r9   r,   r;   r=   lock)rP   rF   rl   r(   ro   rS   r   rp   rn   _validate_reentranttimeperf_counterr)   acquirer   rx   secrets	token_hex_acquire_writer_slot_acquire_reader_slotrj   Eventr:   _refresh_markerrH   r   r1   	get_identstartr   )rs   r4   rP   rF   effective_timeouteffective_blockingrV   r   acquiredr   r,   r7   r9   r   	heartbeats                  r$   r   zSoftReadWriteLock._acquire  s    -4ODLL.6.>T]]H[[!! 	6%%-dnn-==qr"3''||-dnn-==MN"3''zz%//5	6 	6 &	6 !!#!{{..666FH"${{..666EH{{..66N_6`H$..)t3'	.%% :::)33D9: :L KK##++-K *:  1B6tEDU<UH%%b)Ew)-)B)BH7I *C *&Y *.)B)BH7I *C *&Y #*J(,,00%*2d8A,7	I %% 
"=AW_I$7$7$9RV +'%.#-	

 OO%40KK##++-u	6 	6(: :.
 
 KK##++-sO   A+K1L 4K>	L  B7L 72L)#L 1K;>LL LL &L=c                   | j                   }|J |j                  |k7  rB|dk(  rdnd}|dk(  rdnd}d| d| j                   dt        |        d| d	| d
}t	        |      |dk(  rYt        j                         x}|j                  k7  r6d| j                   dt        |        d| d|j                   }t	        |      |xj                  dz  c_        t        |       S )Nr   r   	downgradeupgradezCannot acquire z	 lock on r   z): already holding a z lock (z not allowed)zCannot acquire write lock on z) from thread z while it is held by thread r   r   )
rn   r4   rS   r   r   rj   r   r6   r2   r   )rs   r4   r   opposite	directionrV   curs          r$   r   z%SoftReadWriteLock._validate_reentrant  s   zz99"&&.wfH'+v~9I!$y0@BtH: V%%-Jgi[O  s##7?y':':'< <AUAUU//?{2d8* U"e#?@T@T?UW  s##

a
!t,,r#   c                    j                          d fd}d fd} j                  |||       	  j                  |||        j                  j
                  dfS # t        $ r! t         j                  j
                          w xY w)Nc                     j                   j                  5  t         j                  j                   j
                  t        j                                t         j                  j                        r
	 d d d        y	 t         j                  j                         	 d d d        y# t        $ r Y d d d        yw xY w# 1 sw Y   yxY w)NrI   nowFT)
rl   r   _break_stale_markerri   r   rI   r   _file_exists_atomic_create_markerFileExistsError)rs   r,   s   r$   try_claim_writerz@SoftReadWriteLock._acquire_writer_slot.<locals>.try_claim_writer  s    "" !#DKK$5$5tG[G[aeajajalm 1 12 ! !!)$++*;*;UC!  ' ! ! !!! s*   AC B++	B?4C>B??CCc                 J    j                   j                  5  t        t              5  t	         j
                  j                         d d d         j                  t        j                                 j                          cd d d        S # 1 sw Y   FxY w# 1 sw Y   y xY wN)
rl   r   r   r   _touchri   r   _break_stale_readersr   _any_readersr   s   r$   readers_drained_touchingzHSoftReadWriteLock._acquire_writer_slot.<locals>.readers_drained_touching   s~    "" / g& .4;;,,-.))$))+6,,../ /. ./ /s"   B B;BB	BB"r   Fr]   r8   )_open_readers_dir	_wait_forr   r   ri   r   )rs   r,   r   rF   r   r   s   ``    r$   r   z&SoftReadWriteLock._acquire_writer_slot  s     	 			/ 	'(XN	NN3hQYNZ
 {{  %''	  	DKK%%&	s   A! !*Bc               T     j                          t        j                         j                   dt	        j
                           j                  t        t         j                  j                        z        d fd} j                  |||       dfS dfS )N.c                 f   j                   j                  5  t        j                  j                  j
                  t        j                                t        j                  j                        r
	 d d d        y t                nt               	 d d d        y# 1 sw Y   y xY w)Nr   Fr   T)	rl   r   r   ri   r   rI   r   r   r   )r   full_reader_pathreader_namers   r,   s   r$   try_claim_readerz@SoftReadWriteLock._acquire_reader_slot.<locals>.try_claim_reader  s    "" #DKK$5$5tG[G[aeajajalm 1 12   %)+uVL)*:EB  s   AB' B''B0r   Tr   )r   uuiduuid4hexrg   getpidrm   r   r   ri   r   r   )rs   r,   r   rF   r   r   r   r   s   ``   @@@r$   r   z&SoftReadWriteLock._acquire_reader_slot  s     	 ))*!BIIK=9%%tDKK$7$78;FG		 		 	'(XN%1$NN7G$NNr#   c                  	  |       ry t        j                         }|st        | j                        |||k\  rt        | j                        | j                  }|t        |t        ||z
  d            }t        j                  |       )Ng        )r   r   r   rS   rJ   minmaxsleep)rs   	predicater   rF   r   	sleep_fors         r$   r   zSoftReadWriteLock._wait_for,  s     {##%Cdnn--#xdnn--**I#	3x#~s+CD	JJy! r#   c                   t        | j                  j                        }t        t              5  |j                  d       d d d        t        j                  | j                  j                        }t        j                  |j                        st        j                  |j                        s$| j                  j                   d}t        |      | j                  `t        rYt        j                  t!        t        dd      z  t"        z  }t        j$                  | j                  j                  |      | _        y y y # 1 sw Y   xY w)Ni  )r4   zB exists but is not a directory or is a symlink; refusing to use itO_DIRECTORYr   )r   ri   r   r   r   mkdirrg   lstatstatS_ISLNKst_modeS_ISDIRr   rm   _SUPPORTS_DIR_FDO_RDONLYgetattr_O_NOFOLLOWopen)rs   readers_pathstrV   flagss        r$   r   z#SoftReadWriteLock._open_readers_dir@  s    DKK//0o& 	+E*	+ XXdkk))*<<

#4<<

+C[[(())klCs##',<KK'"mQ"??+ME#%774;;+>+>#FD  -='	+ 	+s   EEc                0    | j                         D ]  } y y)NTF)_iter_reader_entries)rs   _s     r$   r   zSoftReadWriteLock._any_readersN  s     **, 	A	r#   c              #    K   | j                   Wt        j                  | j                         5 }|D ](  }t        |j                        r|j                  df * 	 ddd       yt        | j                  j                        }t        j                  |      5 }|D ]4  }t        |j                        rt        ||j                  z        df 6 	 ddd       y# 1 sw Y   yxY w# 1 sw Y   yxY ww)a#  
        Yield ``(name, dirfd_relative)`` pairs for every live reader marker.

        ``dirfd_relative`` is ``True`` when *name* should be passed to ``dir_fd=``-aware syscalls; ``False``
        when *name* is a full path because dirfd-relative I/O is unavailable on this platform.
        NTF)	rm   rg   scandir_is_housekeeping_namer   r   ri   r   r   )rs   itentryr   s       r$   r   z&SoftReadWriteLock._iter_reader_entriesS  s      +D001 /R /E0<#jj$..// DKK//0ZZ% 	@ @,UZZ8lUZZ78%??@	@ 	@/ 	@ 	@s@   ,C6C
C=C6C*6C*	C6C'#C6*C3/C6c                    g }	 | j                         D ]&  \  }}|j                  ||r| j                  nd f       ( 	 |D ]  \  }}t	        || j
                  ||         y # t        $ r Y y w xY w)N)rI   r   r   )r   appendrm   r   r   rI   )rs   r   namesr   dirfd_relativefds         r$   r   z&SoftReadWriteLock._break_stale_readersf  s    .0	(,(A(A(C W$ndND$8$8PTUVW  	`HD"d6J6JPS\^_	`  		s   9A" "	A.-A.c                   | j                   j                  5  | j                  }|
	 d d d        y|j                  }|j                  }|j
                  r| j                  nd }d d d        t              }|y|\  }}| t        j                  |j                        sy	 t        ||       y# 1 sw Y   PxY w# t        $ r Y yw xY w)NFr   T)rl   r(   rn   r7   r,   r9   rm   _read_markerhmaccompare_digestr   FileNotFoundError)rs   r   r7   r,   r   read_resultinfo_mtimes           r$   r   z!SoftReadWriteLock._refresh_markerp  s    [[!! 	F::D|	F 	F **KJJE-1^^T))F	F #;v>"f <t224::uE	;v. )	F 	F$ ! 		s"   B12B1#B= 1B:=	C	C	c                    t        t        j                         t        j                         t        | j                  j
                  d            | _        d | _        d | _        d| _	        y )NrY   re   rf   T)
r&   rj   rk   r   ri   r   rl   rn   rm   ro   r   s    r$   _reset_after_fork_in_childz,SoftReadWriteLock._reset_after_fork_in_child  sQ     ^^%!(t{{00"=

 
#!%r#   rX   )rS   rZ   rP   r[   rF   r8   rG   r8   rH   r[   rI   r\   rJ   r[   r]   Noner   )rP   r\   rF   bool | Noner]   zGenerator[None])rP   r\   rF   r  r]   r   r]   r   )r   r8   r]   r   )rS   rZ   rP   r[   rF   r8   r]   r^   )r4   r3   rP   r\   rF   r  r]   r   )r4   r3   r]   r   )r,   r   r   r\   rF   r8   r]   ztuple[str, bool])r   Callable[[], bool]r   r\   rF   r8   r]   r   r   )r]   zGenerator[tuple[str, bool]])r   r[   r]   r   )r   r   r    r>   r
   rA   r!   rj   rk   rB   rt   r   rz   r~   rw   r}   r   rx   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r"   r#   r$   r^   r^      s$   ,\ @S?TJ<T$inn&O
 0
 !$((,#0)0 0
 0 0 "0 &0 0 
0d QU  & RV  &ATX A.BUY B6," (- (&T  :
 :): :
 : 
: :*D.D. D.
 D. 
D.L-(&(&( 	&(
 &( 
&(POO 	O
 O 
O4"%" 	"
 " 
"(G
@&`.&r#   r^   )	metaclassc                  <     e Zd Z	 	 	 	 	 	 	 	 	 	 d fdZddZ xZS )r:   c                R    t         |   |d       || _        || _        || _        y )NT)r   daemon)rL   rt   _refresh	_interval_stop_event)rs   r   r   r   r   rW   s        r$   rt   z_HeartbeatThread.__init__  s-     	d40!%r#   c                    | j                   j                  | j                        sR| j                         s| j                   j	                          y | j                   j                  | j                        sQy y r   )r  waitr
  r	  r   r   s    r$   runz_HeartbeatThread.run  sR    ""''7==?  $$& ""''7r#   )
r   r  r   r[   r   r<   r   r   r]   r   r  )r   r   r    rt   r  r_   r`   s   @r$   r:   r:     s=    
&#
& 
& $	
&
 
& 

&r#   r:   r   c                  t         j                  t         j                  z  t         j                  z  t        z  }t
        r|t        j                  | |d|      }nt        j                  | |d      }	 | dt        j                          dt        j                          dj                  d      }t        j                  ||       t        j                  |       y # t        j                  |       w xY w)Ni  r   
ascii)rg   O_CREATO_EXCLO_WRONLYr   r   r   r   socketgethostnameencoder   r   )r   r,   r   r   r   contents         r$   r   r     s     JJ"R[[0;>EF.WWT5%7WWT5%(G2biik]"V-?-?-A,B"ELLWU
W
s   4AC C5c                  t         j                  t        z  }	 t        r|t        j                  | ||      nt        j                  | |      }	 	 t        j                  |      }t        j                  |t        dz         }	 t        j                  |       t        |      |j                  fS # t
        $ r Y y w xY w# t
        $ r Y t        j                  |       y w xY w# t        j                  |       w xY w)Nr   r   )rg   r   r   r   r   r   fstatr   _MAX_MARKER_SIZEr   _parse_marker_bytesst_mtime)r   r   r   r   r   datas         r$   r   r     s     KK+%E4DI[RWWT50acahahimotau	"B772/!34D 	t$bkk11    	
	 	s5   6B0 2B? 0	B<;B<?	C C# C  C# #C:c                   | rt        |       t        kD  ry 	 | j                  d      }t	        j
                  d|t        j                        }|y t        |d   d      }|dkD  ry t        |d   ||d         S # t        $ r Y y w xY w)	Nr  u  
        \A                                  # start of string
        (?P<token>    [0-9a-f]{32}     ) \n # 128-bit hex token
        (?P<pid>      [1-9][0-9]{0,9}  ) \n # decimal pid: no leading zero, ≤ 10 digits
        (?P<hostname> [\x21-\x7e]{1,253})   # printable non-whitespace ASCII (RFC 1123 hostname limit)
        \n*                                 # tolerate sloppy writers that append extra newlines
        \Z                                  # end of string
        r.   
   ir,   r/   )r,   r.   r/   )	lenr  decodeUnicodeDecodeErrorrematchVERBOSEr-   r+   )r  textr%  r.   s       r$   r  r    s     3t9//{{7# HH	 	


E }
eElB
C
YU7^uZ?PQQ'  s   A9 9	BBc               (   t        | |      }|y|\  }}||z
  |k  ry|t        | |       y|  t         dt        j                          dt        j                  d       }	 t        r|t        j                  | |||       nt        |       j                  |       t        ||      }|y|\  }	}
|	t        ||       yt        j                  |j                  |	j                        sy|
|kD  ryt        ||       y# t        $ r Y yw xY w)Nr   FTr   r   )
src_dir_fd
dst_dir_fd)r   r   _BREAK_SUFFIXrg   r   r   r   r   renamer   r   r   r   r,   )r   rI   r   r   r   info_beforemtime_before
break_name
read_after
info_aftermtime_afters              r$   r   r     s"    tF3K +K
\_,V$6-"))+a8I8I"8M7NOJ 2IIdJ6fMJj) j8J(J
6*{00*2B2BC\!Jv&  s   %<D 	DDc                   t        t              5  t        r|t        j                  | |       nt        |       j	                          d d d        y # 1 sw Y   y xY wNr   )r   r   r   rg   unlinkr   r   r   s     r$   r   r     sF    	#	$   2IId6*J     s   :AAc               r    t         r|t        j                  | d |       y t        j                  | d        y r4  )r   rg   utimer6  s     r$   r   r     s(    F.
tF+
tr#   c                    	 t        j                  |       }t        j                  |j
                        S # t        $ r Y yw xY w)NF)rg   r   r   r   S_ISREGr   )pathr   s     r$   r   r   &  s=    XXd^ <<

##  s   6 	AAc                8    | j                  d      xs t        | v S )Nr   )
startswithr+  )r   s    r$   r   r   .  s    ??38=D#88r#   c                     t        j                         at        t        j                               D ]  } | j                           y r   )rj   rk   rq   listr   valuesr   rU   s    r$   _reset_all_after_forkrB  2  s:    
 $..*..01 .++-.r#   c                     t        t        j                               D ],  } t        t              5  | j                  d       d d d        . y # 1 sw Y   9xY w)NTr   )r?  r   r@  r   	Exceptionrx   rA  s    r$   _cleanup_all_instancesrE  <  sR    ..01 )i  	)4(	) 	))	) 	)s   AA	c                     t         st        j                  t               da t        s.t        t        d      rt        j                  t               day y y )NTregister_at_fork)after_in_child)	_atexit_registeredatexitregisterrE  _fork_registeredhasattrrg   rG  rB  r"   r#   r$   rr   rr   B  sC    ./!,> ?
+@A !@r#   )r   r   r,   r   r   r5   r]   r   )r   r   r   r5   r]   z'tuple[_MarkerInfo | None, float] | None)r  bytesr]   z_MarkerInfo | None)
r   r   rI   r[   r   r[   r   r5   r]   r8   )r   r   r   r5   r]   r   )r;  r   r]   r8   )r   r   r]   r8   r  )Ir>   
__future__r   rJ  r   rg   r$  r   r  r   sysrj   r   r   
contextlibr   r   dataclassesr   pathlibr   typingr   r	   weakrefr
   filelock._apir   filelock._errorr   filelock._softr   filelock._utilr   collections.abcr   r   r3   r+  r  r   r   platformr   supports_dir_fdr   r   r!   rk   rq   rI  rL  r   r&   r+   r1   typer@   r^   Threadr:   r   r   r  r   r   r   r   r   rB  rE  rr   __all__r"   r#   r$   <module>r`     s   ` "   	 	    
    / !  ) ' , # ' 23 	  b,* <<7*Lrww":L:L/L ?R?T< T$inn&    $      $   
$ 
$ 
$.$ .bQ&+ Q&hy'' ( JN  59 2&RF *
* * 
	*
 * 
*Z 04   /3 $9.)  r#   