
    Loj0;                       S SK Jr  S SKrS SKrS SKrS SKJr  S SKJr  S SK	J
r
JrJrJr  S SKJrJr  SSKJr  SS	KJr  SS
KJrJrJrJr  SSKJr  SSKJrJr  \(       a-  S SKrS SK J!r!  SSK"J#r#  \RH                  S:  a  S SKJ%r%  OS SK&J%r%  \S   r'\S   r(\" SS9 " S S5      5       r)\" SS9 " S S5      5       r*\ " S S5      5       r+ " S S5      r, " S S\,\5      r- " S S \5      r./ S!Qr/g)"    )annotationsN)suppress)	dataclass)EventThreadcurrent_threadlocal)TYPE_CHECKINGLiteral   )LeaseSettingsMismatch)owner_is_stale)MarkerSoftFileLock	OwnerModeOwnerRecordparse_marker)_read_lock_file)break_lock_filetouch)Callable)LockOptions)      )Unpack)marker-missingowner-changedrefresh-failed)oklost	transientT)frozenc                  F    \ rS rSr% SrS\S'   S\S'   S\S'   SrS	\S
'   Srg)LeaseCompromise!   z6Why a held lease stopped being this process's to hold.str	lock_filetokenCompromiseReasonreasonNOSError | Noneerror )__name__
__module____qualname____firstlineno____doc____annotations__r+   __static_attributes__r,       I/mnt/workspace/venv-train/lib/python3.13/site-packages/filelock/_lease.pyr#   r#   !   s    @NJ E> r4   r#   c                  .    \ rS rSr% SrS\S'   S\S'   Srg)	
_Heartbeat+   zPA running heartbeat and the event that stops it, which only ever exist together.r   threadr   stopr,   N)r-   r.   r/   r0   r1   r2   r3   r,   r4   r5   r7   r7   +   s    ZN
Kr4   r7   c                  D    \ rS rSr% SrSrS\S'   SrS\S'   SrS\S	'   S
r	g)_LeaseClaim3   zNThe state of one claim: its token, its heartbeat, and how that claim was lost.N
str | Noner'   LeaseCompromise | None
compromisez_Heartbeat | None	heartbeatr,   )
r-   r.   r/   r0   r1   r'   r2   r@   rA   r3   r,   r4   r5   r<   r<   3   s%    XE:)-J&-#'I 'r4   r<   c                  "    \ rS rSrSrSS jrSrg)_LeaseClaimHolder<   z,Holds the claim its owning context acquired.c                "    [        5       U l        g N)r<   claimselfs    r5   __init___LeaseClaimHolder.__init__B   s     ]
r4   )rG   NreturnNone)r-   r.   r/   r0   r1   rJ   r3   r,   r4   r5   rC   rC   <   s
    6
#r4   rC   c                      \ rS rSrSrSrg)_ThreadLocalLeaseClaimHolderF   z:A thread local version of the ``_LeaseClaimHolder`` class.r,   N)r-   r.   r/   r0   r1   r3   r,   r4   r5   rP   rP   F   s    Dr4   rP   c                    ^  \ rS rSr% SrSrS\S'   SrS\S'   S	rS
\S'   SSSS.           SU 4S jjjr	\
S S j5       r\
S!S j5       r\
S"S j5       r\
S#S j5       rS$U 4S jjrS$U 4S jjrS%U 4S jjrS$U 4S jjrS&S jrS'S jrS$S jr            S(S jr          S)S jr          S*S jrSrU =r$ )+SoftFileLeaseJ   a  
Existence lock whose claim expires, so a peer may take it while the previous holder still runs.

A lease trades mutual exclusion for progress. The holder publishes a claim and refreshes it every
``heartbeat_interval`` seconds; a contender takes the marker once it is ``lease_duration`` seconds stale. Nothing
stops the expired holder: it keeps running, and it keeps using whatever the lock protects. Treat the lease as a hint
about who *should* be working, not as a guarantee that only one worker is.

To make a protected resource reject a superseded holder, that resource must be linearizable and must fence on a
monotonic generation it controls. :attr:`token` names a claim; it does not fence one. Where overlap is unacceptable,
use :class:`StrictSoftFileLock <filelock.StrictSoftFileLock>` instead.

Every contender for a path must agree on ``lease_duration``. A contender that finds a claim published under a
different duration raises :class:`LeaseSettingsMismatch <filelock.LeaseSettingsMismatch>` rather than apply its own
expiry to a peer that never agreed to it.

Expiry reclaims less on Windows, which refuses to rename or delete a file another process holds open. A peer there
takes an expired claim only once the previous holder's process exits and its handle closes; a holder that lives on
but stops refreshing keeps the marker. Unix reclaims the marker either way.

``on_compromise`` fires from the heartbeat thread when a refresh fails, or when the marker vanishes or names another
owner. The holder should stop touching the protected resource when it runs. Because it runs on that thread, a
``release()`` inside it only takes effect when the lease was built with ``thread_local=False``; the default
thread-local context hides the claim from every thread but the one that acquired it, so the release does nothing.
Signal the acquiring thread instead when the context stays thread-local.

.. versionadded:: 3.30.0

leaser   _owner_modeFbool_lifetime_supportedz(lease_duration sets when a lease expiresr%   _lifetime_unsupported_reasong      >@N)lease_durationheartbeat_intervalon_compromisec                  > US::  a  SU< 3n[        U5      eUc  US-  nSUs=:  a  U:  d  O  SU< 3n[        U5      e[        TU ]  " U40 UD6  X l        X0l        X@l        U R                  5       (       a  [        O[        " 5       U l	        g)a'  
Create a lease.

:param lease_duration: seconds of marker staleness after which a contender may take the claim. Every contender
    for the path must pass the same value.
:param heartbeat_interval: seconds between refreshes. Defaults to a third of ``lease_duration``, leaving room
    for two missed refreshes before a peer may take the claim. Must be shorter than ``lease_duration``.
:param on_compromise: called from the heartbeat thread with a :class:`LeaseCompromise` when the claim is lost.
:param kwargs: every other :class:`BaseFileLock <filelock.BaseFileLock>` option, ``timeout`` and ``mode`` among
    them. The metaclass passes them all by keyword, and taking them here lets
    :class:`AsyncSoftFileLease <filelock.AsyncSoftFileLease>` add the async plumbing a fixed signature would
    hide.

r   z%lease_duration must be positive, got Nr   zBheartbeat_interval must be positive and below lease_duration, got )

ValueErrorsuperrJ   _lease_duration_heartbeat_interval_on_compromiseis_thread_localrP   rC   _claims)rI   r&   rZ   r[   r\   kwargsmsg	__class__s          r5   rJ   SoftFileLease.__init__o   s    . Q9.9KLCS/!%!/!!3%66VWiVlmCS/!-f--#5 + -1,@,@,B,B(HYY+r4   c                .    U R                   R                  $ rF   )rd   rG   rH   s    r5   _claimSoftFileLease._claim   s    ||!!!r4   c                    U R                   $ )zEThe staleness in seconds after which a contender may take this claim.)r`   rH   s    r5   rZ   SoftFileLease.lease_duration   s     ###r4   c                .    U R                   R                  $ )z
The token naming the claim this process published.

:returns: the token while the lease is held, ``None`` otherwise. It identifies a claim; it does not fence one.

)rj   r'   rH   s    r5   r'   SoftFileLease.token   s     {{   r4   c                .    U R                   R                  $ )z}
The loss of claim the heartbeat observed.

:returns: the :class:`LeaseCompromise`, or ``None`` while the claim still holds

)rj   r@   rH   s    r5   r@   SoftFileLease.compromise   s     {{%%%r4   c                0  > U R                   nU R                  5         [        R                  " S5      =Ul        nS Ul        [        TU ]  5         U R                  R                  =nb.  U R                  R                  =n b  U R                  XXB5        g g g )N   )rj   _stop_heartbeatsecrets	token_hexr'   r@   r_   _acquire_contextlock_file_fdlock_file_fd_identity_start_heartbeat)rI   rG   r'   fdidentityrg   s        r5   rw   SoftFileLease._acquire   s    %//33e --,,,B9;;;H? !!%X=?9r4   c                d   > U R                  5         S U R                  l        [        TU ]  5         g rF   )rt   rj   r'   r_   _releaserI   rg   s    r5   r   SoftFileLease._release   s&     r4   c                x   > [         TU ]  5       R                  U R                  R                  U R
                  S9$ )N)r'   rZ   )r_   _published_record_replacerj   r'   r`   r   s    r5   r   SoftFileLease._published_record   s2    w(*33$++:K:K\`\p\p3qqr4   c                  > U R                  5       =nc  [        TU ]	  5         g Uu  p#nUR                  S:w  a  g UR                  U R
                  :w  a6  U R                   SUR                  < SU R
                  < S3n[        U5      e[        [        5         [        UR                  UR                  UR                  5      (       a   [        U R                  X45         S S S 5        g [        R                  " 5       U-
  U R
                  :  a  [        U R                  X45        S S S 5        g ! , (       d  f       g = f)NrU   z holds a lease of z s but this contender configured z:s; every contender for a path must agree on lease_duration)
_read_peerr_   _try_break_stale_lockmoderZ   r`   r&   r   r   OSErrorr   pidhostnamestartr   time)rI   peerownermtimeinorf   rg   s         r5   r   #SoftFileLease._try_break_stale_lock   s   OO%%D.
 G)+ c :: 4#7#77>>""4U5I5I4LLl''**df  (,, g eiiEE;  yy{U"d&:&::; s   AD/*<D//
D=c                    [        [        [        5         [        U R                  5      u  pn[        U5      =nb  XBU4sS S S 5        $  S S S 5        g ! , (       d  f       g = frF   )r   r   r^   r   r&   r   )rI   contentr   r   r   s        r5   r   SoftFileLease._read_peer   sZ    gz*"1$.."AGC%g..;S( +*; + 	 +* s   *A
A!c                    [        5       n[        U R                  XX4U4S[        R                  " 5        3SS9n[        Xe5      Ul        UR                  5         g )Nzfilelock-lease-T)targetargsnamedaemon)r   r   _refresh_until_stoppedosgetpidr7   rA   r   )rI   rG   r|   r}   r'   r:   r9   s          r5   r{   SoftFileLease._start_heartbeat   sR     w..Xd3"299;-0	
 %V2r4   c                $   U R                   nUR                  =nc  g UR                  R                  5         S Ul        UR                  R
                  b<  UR                  [        5       La$  UR                  R                  U R                  S9  g g g )N)timeout)	rj   rA   r:   setr9   identr   joinra   )rI   rG   rA   s      r5   rt   SoftFileLease._stop_heartbeat   s~    (I1 !!-)2B2B.JZ2Z!!$*B*B!C 3[-r4   c                   [         R                  " 5       nUR                  U R                  5      (       d  U R	                  XX45      u  pxUS:X  a  g US:X  a  [         R                  " 5       nOG[         R                  " 5       U-
  U R
                  U R                  -
  :  a  U R                  USX5        g UR                  U R                  5      (       d  M  g g )Nr   r   r   )r   	monotonicwaitra   _refresh_claimr`   _report_compromise)	rI   rG   r|   r}   r'   r:   last_successoutcomer+   s	            r5   r   $SoftFileLease._refresh_until_stopped  s     ~~'))D4455!00HLNG& $#~~/!L0D4H4H4KcKc4cc''/?N ))D4455r4   c                    [         R                  " U R                  5      nUR                  UR                  4U:w  a  U R	                  USS U5        g [        U R                  US9  g! [         a  nU R	                  USXd5         S nAgS nAf[
         a  nSU4s S nA$ S nAff = f! [
         a  nSU4s S nA$ S nAff = f)Nr   )r   Nr    r   )r|   )r   N)	r   lstatr&   FileNotFoundErrorr   r   st_devst_inor   )rI   rG   r|   r}   r'   str+   s          r5   r   SoftFileLease._refresh_claim#  s    	&$..)B IIryy!X-##E?D%H	&$..R(  ! 	 ##E+;UJ 	&%%	&  	&%%	&sG    A) B) )
B&3BB&B!B&!B&)
C3B<6C<Cc                    [        U R                  XBUS9Ul        U R                  b  U R                  UR                  5        g g )N)r&   r'   r)   r+   )r#   r&   r@   rb   )rI   rG   r)   r+   r'   s        r5   r    SoftFileLease._report_compromise;  s?     +T^^5glm* 0 01 +r4   )rd   ra   r`   rb   )r&   zstr | os.PathLike[str]rZ   floatr[   zfloat | Noner\   z(Callable[[LeaseCompromise], None] | Nonere   zUnpack[LockOptions]rM   rN   )rM   r<   )rM   r   )rM   r>   )rM   r?   rL   )rM   r   )rM   z%tuple[OwnerRecord, float, int] | None)
rG   r<   r|   intr}   tuple[int, int]r'   r%   rM   rN   )rG   r<   r|   r   r}   r   r'   r%   r:   r   rM   rN   )
rG   r<   r|   r   r}   r   r'   r%   rM   z&tuple[_RefreshOutcome, OSError | None])
rG   r<   r)   r(   r+   r*   r'   r%   rM   rN   )r-   r.   r/   r0   r1   rV   r2   rX   rY   rJ   propertyrj   rZ   r'   r@   rw   r   r   r   r   r{   rt   r   r   r   r3   __classcell__)rg   s   @r5   rS   rS   J   s   < %K$ !&%(R #R !%+/BF')' 	'
 )' @' &' 
' 'R " " $ $ ! ! & &>
r<< 
D  "	
   
0  "	
  
0022 !2 	2
 2 
2 2r4   rS   )r(   r#   rS   )0
__future__r   r   ru   r   
contextlibr   dataclassesr   	threadingr   r   r   r	   typingr
   r   _errorr   	_identityr   _markerr   r   r   r   _softr   _utilr   r   syscollections.abcr   _apir   version_infor   typing_extensionsr(   _RefreshOutcomer#   r7   r<   rC   rP   rS   __all__r,   r4   r5   <module>r      s    " 	    ! : : ) ) % M M " )(!
7"!,NO 34 $! ! ! $   ( ( (# #E#4e E}2& }2@r4   