o
    2j                     @  sl  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ryddl"m#Z#m$Z$ ed Z%dZ&dZ'e(eddZ)e(eddZ*e
j+dkoej,ej-v Z.e Z/de0d< e1 a2da3da4eddG dd dZ5eG dd dZ6eddG dd dZ7eG dd  d Z8G d!d" d"e9Z:G d#d$ d$e:d%Z;G d&d' d'ej<Z=dd(dOd0d1Z>dd(dPd3d4Z?dQd8d9Z@dd(dRd>d?ZAdd(dSd@dAZBdd(dSdBdCZCdTdEdFZDdUdGdHZEdVdIdJZFdVdKdLZGdVdMdNZHd$gZIdS )WzZCross-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
O_NONBLOCKwin32,WeakValueDictionary[Path, SoftReadWriteLock]_all_instancesFT)frozenc                   @  s&   e Zd ZU ded< ded< ded< dS )_Pathsstrstater   readersN__name__
__module____qualname____annotations__ r!   r!   R/var/www/html/whisper/venv/lib/python3.10/site-packages/filelock/_soft_rw/_sync.pyr   .      
 r   c                   @  s&   e Zd ZU ded< ded< ded< dS )_Locksthreading.Lockinternaltransactionr   r   Nr   r!   r!   r!   r"   r$   5   r#   r$   c                   @  s&   e Zd ZU ded< ded< ded< dS )_MarkerInfor   tokenintpidhostnameNr   r!   r!   r!   r"   r(   <   r#   r(   c                   @  sR   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< dS )_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!   r"   r-   C   s   
 r-   c                      sB   e Zd ZU ded< ded< 	dddddd	d
d fddZ  ZS )_SoftRWMetar   
_instancesr%   _instances_lockT      >@N      ?blockingis_singletonheartbeat_intervalstale_thresholdpoll_interval	lock_filestr | os.PathLike[str]timeoutfloatrB   r4   rC   rD   rE   float | NonerF   returnSoftReadWriteLockc             
     s   |st  j|||||||dS t| }| jE | j|}	|	d u r6t  j|||||||d}	|	| j|< n|	j|ks@|	j|krTd|	j d|	j d| d| }
t	|
|	W  d    S 1 s`w   Y  d S )NrA   z$Singleton lock created with timeout=z, blocking=z, cannot be changed to timeout=)
super__call__r   resolver=   r<   getrI   rB   
ValueError)clsrG   rI   rB   rC   rD   rE   rF   
normalizedinstancemsg	__class__r!   r"   rO   U   sD   
	$z_SoftRWMeta.__call__r>   )rG   rH   rI   rJ   rB   r4   rC   r4   rD   rJ   rE   rK   rF   rJ   rL   rM   )r   r   r   r    rO   __classcell__r!   r!   rW   r"   r;   Q   s   
 r;   c                   @  s>  e Zd ZU dZe Zded< e Z		dRdddddd	dSddZ
edTdddUddZedTdddUddZdTdddVd!d"ZdTdddVd#d$ZdWd%d&Zd'd(dXd*d+Ze	dRdddYd,d-ZdZd0d1Zd[d4d5Zd\d6d7Zd]d<d=Zd]d>d?Zd^dBdCZdWdDdEZd_dFdGZd`dIdJZdadLdMZd_dNdOZdWdPdQZdS )brM   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   r<   r>   Tr?   Nr@   rA   rG   rH   rI   rJ   rB   r4   rC   rD   rE   rK   rF   rL   Nonec          	      C  s@  |dkrd| }t ||d u r|d }||kr&d| d| d}t ||dkr3d| }t |t|| _|| _|| _|| _|| _|| _t	| j d| j d	| j d
d| _
t| j tt t t| j
jddd| _d | _d | _d| _d| _t | tt| j < t  W d    d S 1 sw   Y  d S )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   r>   rI   r&   r'   r   F)rR   osfspathrG   rI   rB   rD   rE   rF   r   _pathsr   r$   	threadingLockr   r   _locks_readers_dir_fd_hold_fork_invalidated_closed_all_instances_lockr   r   rP   _register_hooks)	selfrG   rI   rB   rC   rD   rE   rF   rV   r!   r!   r"   __init__   sH   





"zSoftReadWriteLock.__init__rB   bool | NoneGenerator[None]c                c  0    | j ||d z
dV  W |   dS |   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

        rn   N)acquire_readreleaserl   rI   rB   r!   r!   r"   	read_lock   
   zSoftReadWriteLock.read_lockc                c  rq   )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

        rn   N)acquire_writers   rt   r!   r!   r"   
write_lock   rv   zSoftReadWriteLock.write_lockr
   c                C     | j d||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   rn   _acquirert   r!   r!   r"   rr     s   zSoftReadWriteLock.acquire_readc                C  ry   )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   rn   rz   rt   r!   r!   r"   rw   %  s   zSoftReadWriteLock.acquire_writec              	   C  s   | j dd | jjB | jr	 W d   dS d| _| jdurDtt t| j W d   n1 s4w   Y  d| _W d   dS W d   dS 1 sOw   Y  dS )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)	rs   re   r&   ri   rf   r   OSErrorr`   closerl   r!   r!   r"   r   @  s   


"zSoftReadWriteLock.closeFr|   r}   c                C  s  | j jW | jrd| _	 W d   dS | j}|du r6|r&	 W d   dS d| j dt|  d}t||r<d|_n| jd8  _|jdkrQ	 W d   dS d| _W d   n1 s^w   Y  |j	  |j
j| jd d |jrt|j| jd	 dS t|j dS )
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      ?r^   dir_fd)re   r&   rh   rg   rG   idRuntimeErrorr.   r9   setr7   joinrD   r5   _unlinkr3   rf   )rl   r}   holdrV   r!   r!   r"   rs   Q  s2   
	

zSoftReadWriteLock.releasec                C  s   | |||d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

        rn   r!   )rS   rG   rI   rB   r!   r!   r"   get_lock{  s   zSoftReadWriteLock.get_lockr0   r/   c                C  s0  |d u r| j n|}|d u r| jn|}| jj5 | jr%d| j d}t|| jr3d| j d}t|| jd urD| 	|W  d    S W d    n1 sNw   Y  t
 }|sb| jjjdd}n|dkro| jjjdd}n	| jjjd|d}|st| jd z| j||||dW | jj  S | jj  w )	NzSoftReadWriteLock on z4 was invalidated by fork(); construct a new instancez has been closedFrn   r>   T)rB   rI   )rI   rB   re   r&   rh   rG   r   ri   rg   _validate_reentranttimeperf_counterr'   acquirer   _do_acquire_innerrs   )rl   r0   rI   rB   rV   startacquiredr!   r!   r"   r{     s2   


zSoftReadWriteLock._acquireeffective_timeoutr   c                C  s&  | j j | jd ur| |W  d    S W d    n1 s w   Y  |dkr+d n|| }td}|dkrC| j|||d\}}n
| j|||d\}}t	 }	t
| j| j|	dt| dd}
| j j td||dkrqt nd ||||
|	d	| _W d    n1 sw   Y  |
  t| d
S )Nr>      r   deadlinerB   zfilelock-heartbeat-x)refreshinterval
stop_eventnamer   )r.   r0   r2   r3   r5   r)   r7   r9   lock)re   r&   rg   r   secrets	token_hex_acquire_writer_slot_acquire_reader_slotrc   Eventr6   _refresh_markerrD   r   r-   	get_identr   r
   )rl   r0   r   r   rB   r   r)   r3   r5   r   	heartbeatr!   r!   r"   r     s@   





z#SoftReadWriteLock._do_acquire_innerc                 C  s   | j }|d us	J |j|kr7|dkrdnd}|dkrdnd}d| d| j dt|  d| d	| d
}t||dkrZt  }|jkrZd| j dt|  d| d|j }t|| jd7  _t	| d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   )
rg   r0   rG   r   r   rc   r   r2   r.   r
   )rl   r0   r   opposite	directionrV   curr!   r!   r"   r     s,   

z%SoftReadWriteLock._validate_reentrantr)   r   r   tuple[str, bool]c                  st       d	 fdd}d	 fdd} j|||d z
 j|||d W n ty3   t jj  w  jjdfS )
NrL   r4   c                	     s    j j> t jj jt d t jjr 	 W d    dS z	t jj W n t	y9   Y W d    dS w W d    dS 1 sEw   Y  dS )NrE   nowFT)
re   r   _break_stale_markerrb   r   rE   r   _file_exists_atomic_create_markerFileExistsErrorr!   rl   r)   r!   r"   try_claim_writer  s    

z@SoftReadWriteLock._acquire_writer_slot.<locals>.try_claim_writerc                	     sx    j j. tt t jj W d    n1 sw   Y   t   	  W  d    S 1 s5w   Y  d S N)
re   r   r   r~   _touchrb   r   _break_stale_readersr   _any_readersr!   r   r!   r"   readers_drained_touching  s   

$zHSoftReadWriteLock._acquire_writer_slot.<locals>.readers_drained_touchingr   FrL   r4   )_open_readers_dir	_wait_forr   r   rb   r   )rl   r)   r   rB   r   r   r!   r   r"   r     s   		z&SoftReadWriteLock._acquire_writer_slotc                  sx      t j dt  j ttj	j
 d fdd}j|||d  d ur8dfS dfS )	N.rL   r4   c                     s   j j6 tjjjt d tjjr 	 W d    dS  d ur,t d nt 	 W d    dS 1 s=w   Y  d S )Nr   Fr   T)	re   r   r   rb   r   rE   r   r   r   r!   r   full_reader_pathreader_namerl   r)   r!   r"   try_claim_reader!  s   

$z@SoftReadWriteLock._acquire_reader_slot.<locals>.try_claim_readerr   Tr   )r   uuiduuid4hexr`   getpidrf   r   r   rb   r   r   )rl   r)   r   rB   r   r!   r   r"   r     s   z&SoftReadWriteLock._acquire_reader_slot	predicateCallable[[], bool]c                C  sj   	 | rd S t  }|st| j|d ur||krt| j| j}|d ur/t|t|| d}t | q)NTg        )r   r   r   rG   rF   minmaxsleep)rl   r   r   rB   r   	sleep_forr!   r!   r"   r   /  s   


zSoftReadWriteLock._wait_forc                 C  s   t | jj}tt |jdd W d    n1 sw   Y  t| jj}t	|j
s3t|j
s>| jj d}t|| jd u r[tr]tjttddB tB }t| jj|| _d S d S d S )Ni  )r0   zB exists but is not a directory or is a symlink; refusing to use itO_DIRECTORYr   )r   rb   r   r   r   mkdirr`   lstatstatS_ISLNKst_modeS_ISDIRr   rf   _SUPPORTS_DIR_FDO_RDONLYgetattr_O_NOFOLLOWopen)rl   readers_pathstrV   flagsr!   r!   r"   r   C  s   
z#SoftReadWriteLock._open_readers_dirc                 C  s   |   D ]} dS dS )NTF)_iter_reader_entries)rl   _r!   r!   r"   r   Q  s   zSoftReadWriteLock._any_readersGenerator[tuple[str, bool]]c                 c  s    | j dur/t| j }|D ]}t|js|jdfV  qW d   dS 1 s(w   Y  dS t| jj}t|}|D ]}t|jsNt||j dfV  q=W d   dS 1 sZw   Y  dS )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)	rf   r`   scandir_is_housekeeping_namer   r   rb   r   r   )rl   itentryr   r!   r!   r"   r   V  s(   



"z&SoftReadWriteLock._iter_reader_entriesr   c                 C  sl   g }z|   D ]\}}|||r| jnd f qW n
 ty#   Y d S w |D ]\}}t|| j||d q&d S )N)rE   r   r   )r   appendrf   r~   r   rE   )rl   r   namesr   dirfd_relativefdr!   r!   r"   r   i  s   z&SoftReadWriteLock._break_stale_readersc                 C  s   | j j& | j}|d u r	 W d    dS |j}|j}|jr!| jnd }W d    n1 s-w   Y  t||d}|d u r>dS |\}}|d u sMt	|j|sOdS z	t
||d W dS  tyb   Y dS  tyk   Y dS w )NFr   T)re   r&   rg   r3   r)   r5   rf   _read_markerhmaccompare_digestr   FileNotFoundErrorr~   )rl   r   r3   r)   r   read_resultinfo_mtimer!   r!   r"   r   s  s0   
z!SoftReadWriteLock._refresh_markerc                 C  s:   t t t t| jjddd| _d | _d | _d| _	d S )Nr>   r^   r_   T)
r$   rc   rd   r   rb   r   re   rg   rf   rh   r   r!   r!   r"   _reset_after_fork_in_child  s   
z,SoftReadWriteLock._reset_after_fork_in_childrY   )rG   rH   rI   rJ   rB   r4   rC   r4   rD   rJ   rE   rK   rF   rJ   rL   r[   r   )rI   rK   rB   ro   rL   rp   )rI   rK   rB   ro   rL   r
   rL   r[   )r}   r4   rL   r[   )rG   rH   rI   rJ   rB   r4   rL   rM   )r0   r/   rI   rK   rB   ro   rL   r
   )
r0   r/   r   rJ   r   rJ   rB   r4   rL   r
   )r0   r/   rL   r
   )r)   r   r   rK   rB   r4   rL   r   )r   r   r   rK   rB   r4   rL   r[   r   )rL   r   )r   rJ   rL   r[   ) r   r   r   r:   r	   r<   r    rc   rd   r=   rm   r   ru   rx   rr   rw   r   rs   classmethodr   r{   r   r   r   r   r   r   r   r   r   r   r   r!   r!   r!   r"   rM      sJ   
 .2
*

"
&

(






rM   )	metaclassc                      s(   e Zd Zd fddZdddZ  ZS )r6   r   r   r   rJ   r   r8   r   r   rL   r[   c                   s&   t  j|dd || _|| _|| _d S )NT)r   daemon)rN   rm   _refresh	_interval_stop_event)rl   r   r   r   r   rW   r!   r"   rm     s   
z_HeartbeatThread.__init__c                 C  s:   | j | js|  s| j   d S | j | jrd S d S r   )r   waitr   r   r   r   r!   r!   r"   run  s
   
z_HeartbeatThread.run)
r   r   r   rJ   r   r8   r   r   rL   r[   r   )r   r   r   rm   r   rZ   r!   r!   rW   r"   r6     s    r6   r   r   r   r)   r   r1   rL   r[   c             	   C  s   t jt jB t jB tB }tr|d urt j| |d|d}nt | |d}z | dt   dt	  d
d}t || W t | d S t | w )Ni  r   
ascii)r`   O_CREATO_EXCLO_WRONLYr   r   r   r   socketgethostnameencoder   r   )r   r)   r   r   r   contentr!   r!   r"   r     s   $r   'tuple[_MarkerInfo | None, float] | Nonec             	   C  s   t jtB tB }ztr|d urt j| ||dnt | |}W n
 ty'   Y d S w z'zt |}t |t	d }W n tyH   Y W t 
| d S w W t 
| nt 
| w t||jfS )Nr   r   )r`   r   r   _O_NONBLOCKr   r   r~   fstatr   _MAX_MARKER_SIZEr   _parse_marker_bytesst_mtime)r   r   r   r   r   datar!   r!   r"   r     s"   ,
r   r  bytes_MarkerInfo | Nonec                 C  s   | rt | tkr
d S z| d}W n
 ty   Y d S w td|tj}|d u r*d S t|d d}|dkr7d S t|d ||d dS )	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+   r!   r!   r"   r    s$   r  rE   rJ   r   r4   c                C  s  t | |d}|d u rdS |\}}|| |krdS |d u r$t| |d dS |  t dt  dtd }ztrF|d urFtj| |||d nt	| | W n
 t
yX   Y dS w t ||d}|d u redS |\}	}
|	d u rut||d dS t|j|	jsdS |
|krdS t||d dS )Nr   FTr   r   )
src_dir_fd
dst_dir_fd)r   r   _BREAK_SUFFIXr`   r   r   r   r   renamer   r~   r   r   r)   )r   rE   r   r   r   info_beforemtime_before
break_name
read_after
info_aftermtime_afterr!   r!   r"   r     s>   "r   c                C  sf   t t% tr|d urtj| |d nt|   W d    d S W d    d S 1 s,w   Y  d S Nr   )r   r   r   r`   unlinkr   r   r   r!   r!   r"   r   !  s   
"r   c                C  s0   t r|d urtj| d |d d S t| d  d S r  )r   r`   utimer  r!   r!   r"   r   *  s   r   pathc                 C  s0   zt | }W n
 ty   Y dS w t|jS )NF)r`   r   r   r   S_ISREGr   )r  r   r!   r!   r"   r   1  s   r   c                 C  s   |  dpt| v S )Nr   )
startswithr  )r   r!   r!   r"   r   9  s   r   c                  C  s&   t  att D ]} |   q
d S r   )rc   rd   rj   listr   valuesr   rU   r!   r!   r"   _reset_all_after_fork=  s   
r$  c               	   C  sJ   t t D ]} tt | jdd W d    n1 sw   Y  qd S )NTr|   )r!  r   r"  r   	Exceptionrs   r#  r!   r!   r"   _cleanup_all_instancesG  s   
r&  c                   C  s<   t s	tt da tsttdrtjtd dad S d S d S )NTregister_at_fork)after_in_child)	_atexit_registeredatexitregisterr&  _fork_registeredhasattrr`   r'  r$  r!   r!   r!   r"   rk   M  s   
rk   )r   r   r)   r   r   r1   rL   r[   )r   r   r   r1   rL   r   )r  r  rL   r  )
r   r   rE   rJ   r   rJ   r   r1   rL   r4   )r   r   r   r1   rL   r[   )r  r   rL   r4   )r   r   rL   r4   r   )Jr:   
__future__r   r*  r   r`   r  r   r   r   sysrc   r   r   
contextlibr   r   dataclassesr   pathlibr   typingr   r   weakrefr	   filelock._apir
   filelock._errorr   filelock._softr   filelock._utilr   collections.abcr   r   r/   r  r  r   r   r   platformr   supports_dir_fdr   r   r    rd   rj   r)  r,  r   r$   r(   r-   typer;   rM   Threadr6   r   r   r  r   r   r   r   r   r$  r&  rk   __all__r!   r!   r!   r"   <module>   s~    1    !
#-	





