
    NgE              	       <   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mZ  ej        e          ZdZdZdZej        j        ej        j        z  ZddgZe	j        eej        f         Zdd	d
e	j        de	j        de	j        fdZej         	 ddede!de	j"        e	j#                 fd            Z$ G d de j%                  Z& G d de&          Z' G d de'          Z( G d de'          Z) G d de&          Z* G d de*          Z+dS )    N   )	constants
exceptionsportalocker   g      ?FLockopen_atomic)
test_valueargsr
   returnc                 <     t           fd|D             d          S )a  Simple coalescing function that returns the first value that is not
    equal to the `test_value`. Or `None` if no value is valid. Usually this
    means that the last given value is the default value.

    Note that the `test_value` is compared using an identity check
    (i.e. `value is not test_value`) so changing the `test_value` won't work
    for all values.

    >>> coalesce(None, 1)
    1
    >>> coalesce()

    >>> coalesce(0, False, True)
    0
    >>> coalesce(0, False, True, test_value=0)
    False

    # This won't work because of the `is not test_value` type testing:
    >>> coalesce([], dict(spam='eggs'), test_value=[])
    []
    c              3   $   K   | ]
}|u|V  d S N ).0argr
   s     M/var/www/html/ai-engine/env/lib/python3.11/site-packages/portalocker/utils.py	<genexpr>zcoalesce.<locals>.<genexpr>4   s-      >>:(=(=(=(=(=(=>>    N)next)r
   r   s   ` r   coalescer      s*    , >>>>>>>EEEr   Tfilenamebinaryc              #     K   t          j        |           }|                                rJ |d            |j                            dd           t          j        |rdpdt          |j                  d          }|V  |                                 t          j
        |                                           |                                 	 t          j        |j        |           t          j        t"                    5  t          j        |j                   ddd           dS # 1 swxY w Y   dS # t          j        t"                    5  t          j        |j                   ddd           w # 1 swxY w Y   w xY w)	a6  Open a file for atomic writing. Instead of locking this method allows
    you to write the entire file and move it to the actual location. Note that
    this makes the assumption that a rename is atomic on your platform which
    is generally the case but not a guarantee.

    http://docs.python.org/library/os.html#os.rename

    >>> filename = 'test_file.txt'
    >>> if os.path.exists(filename):
    ...     os.remove(filename)

    >>> with open_atomic(filename) as fh:
    ...     written = fh.write(b'test')
    >>> assert os.path.exists(filename)
    >>> os.remove(filename)

    >>> import pathlib
    >>> path_filename = pathlib.Path('test_file.txt')

    >>> with open_atomic(path_filename) as fh:
    ...     written = fh.write(b'test')
    >>> assert path_filename.exists()
    >>> path_filename.unlink()
    z existsT)parentsexist_okwbwF)modedirdeleteN)pathlibPathexistsparentmkdirtempfileNamedTemporaryFilestrflushosfsyncfilenocloserenamename
contextlibsuppress	Exceptionremove)r   r   pathtemp_fhs       r   r	   r	   7   s     < !h//D{{}}00000000 	KdT222)_#  G
 MMMMMOOOHW^^MMOOO$
	',%%% ++ 	$ 	$Igl###	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$Z ++ 	$ 	$Igl###	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$sB   D; D..D25D2;FE;/F;E??FE?Fc                   J   e Zd ZU eed<   eed<   eed<   	 	 	 ddej        e         dej        e         dej        e         fdZe	j
        	 	 	 ddej        e         dej        e         dej        e         dej        ej                 fd            Zdej        e         dej        e         dej        e         fdZe	j
        d	             Zdej        ej                 fd
Zdej        ej        e                  dej        e         dej        dej        e         fdZd ZdS )LockBasetimeoutcheck_intervalfail_when_lockedNc                     t          |t                    | _        t          |t                    | _        t          |t
                    | _        d S r   )r   DEFAULT_TIMEOUTr9   DEFAULT_CHECK_INTERVALr:   DEFAULT_FAIL_WHEN_LOCKEDr;   selfr9   r:   r;   s       r   __init__zLockBase.__init__t   sF      99&~7MNN ($!
 !
r   r   c                     d S r   r   r@   s       r   acquirezLockBase.acquire   s	     $'3r   c              #     K   t          || j        d          }t          || j        d          }dV  d}t          j                    }||z   t          j                    k    rc|dz  }|V  t          j                    |z
  }t          j        t          d||z  |z
                       ||z   t          j                    k    ad S d S )Ng        r   r   gMbP?)r   r9   r:   timeperf_countersleepmax)rA   r9   r:   	f_timeoutf_check_intervali
start_timesince_start_times           r   _timeout_generatorzLockBase._timeout_generator   s      
 WdlC88	#ND4GMM&((
9$t'8':':::FAGGG  $022Z?Js51'7#7;K"KLLMMM 9$t'8':':::::::r   c                     d S r   r   rA   s    r   releasezLockBase.release   s    sr   c                 *    |                                  S r   rD   rQ   s    r   	__enter__zLockBase.__enter__       ||~~r   exc_type	exc_value	tracebackc                 .    |                                   d S r   rR   )rA   rW   rX   rY   s       r   __exit__zLockBase.__exit__   s     	tr   c                 .    |                                  d S r   r[   )rA   instances     r   
__delete__zLockBase.__delete__   s    r   NNN)__name__
__module____qualname__float__annotations__booltypingOptionalrB   abcabstractmethodIOAnyStrrD   IteratorintrO   rR   rU   TypeBaseExceptionAnyr\   r_   r   r   r   r8   r8   l   s        NNN +/1526	
 
'
 .
 !/$/	
 
 
 
 	 +/1526	' ''' .' !/$/	'
 
6=	!' ' ' 'N'N .N 
		N N N N( 	 69V]3    /&+m"<= ?=1 :	
 
	       r   r8   c                   p   e Zd ZdZddeeefdedede	j
        e         deded	ej        fd
Z	 	 	 dde	j
        e         de	j
        e         de	j
        e         de	j        e	j                 fdZde	j        e	j                 fdZd Zde	j        fdZde	j        de	j        fdZde	j        de	j        fdZdS )r   as  Lock manager with built-in timeout

    Args:
        filename: filename
        mode: the open mode, 'a' or 'ab' should be used for writing. When mode
            contains `w` the file will be truncated to 0 bytes.
        timeout: timeout when trying to acquire a lock
        check_interval: check interval while waiting
        fail_when_locked: after the initial lock failed, return an error
            or lock the file. This does not wait for the timeout.
        **file_open_kwargs: The kwargs for the `open(...)` call

    fail_when_locked is useful when multiple threads/processes can race
    when creating a file. If set to true than the system will wait till
    the lock was acquired and then return an AlreadyLocked exception.

    Note that the file is opened first and locked later. So using 'w' as
    mode will result in truncate _BEFORE_ the lock is checked.
    aNr   r   r9   r:   r;   flagsc                 D   d|v rd}|                     dd          }nd}|t          }n*|t          j        j        z  st          j        dd           d | _        t          |          | _	        || _
        || _        || _        || _        || _        || _        || _        d S )Nr   Trs   F&timeout has no effect in blocking moder   
stacklevel)replacer=   r   	LockFlagsNON_BLOCKINGwarningswarnfhr)   r   r   truncater9   r:   r;   rt   file_open_kwargs)	rA   r   r   r9   r:   r;   rt   r   r   s	            r   rB   zLock.__init__   s     $;;H<<S))DDH?%GG)-:: 	M8   
 /3 ]]	&%%3&6*/
 0r   r   c                 n   t          || j                  }| j        t          j        j        z  s|t          j        dd           | j        rS | 	                                fd}d}| 
                    ||          D ]}d}	 |                                nk# t          j        $ r-}|}|r |             t          j        |          |Y d}~Sd}~wt          $ r$} |             t          j        |          |d}~ww xY w|r |             ||                               | _        S )zAcquire the locked filehandleNrv   r   rw   c                       Ht          j        t                    5                                    d d d            d S # 1 swxY w Y   d S d S r   )r1   r2   r3   r.   )r~   s   r   	try_closezLock.acquire.<locals>.try_close  s    ~(33  HHJJJ                  ~s   ?AA)r   r;   rt   r   rz   r{   r|   r}   r~   _get_fhrO   	_get_lockr   LockExceptionAlreadyLockedr3   _prepare_fh)	rA   r9   r:   r;   r   	exception_excr~   s	           @r   rD   zLock.acquire   s    $$4d6KLL i1>>	#M8    *. 	I \\^^	 	 	 	 	 	((.AA 	= 	=AI=^^B''+ 	G 	G 	G  	 $ GIKKK$29==3FG G G G G  = = = 	 .s33<	=  	IKKKO b!!	s$   	B  D/#CD$DDc                 *    |                                  S r   rT   rQ   s    r   rU   zLock.__enter__-  rV   r   c                     | j         r;t          j        | j                    | j                                          d| _         dS dS )z)Releases the currently locked file handleN)r~   r   unlockr.   rQ   s    r   rR   zLock.release0  sC    7 	tw'''GMMOOODGGG	 	r   c                 <    t          | j        | j        fi | j        S )zGet a new filehandle)openr   r   r   rQ   s    r   r   zLock._get_fh7  s0    MI
 
 #
 
 	
r   r~   c                 :    t          j        || j                   |S )zT
        Try to lock the given filehandle

        returns LockException if it fails)r   lockrt   rA   r~   s     r   r   zLock._get_lock?  s    
 	TZ(((	r   c                 h    | j         r*|                    d           |                     d           |S )z
        Prepare the filehandle for usage

        If truncate is a number, the file will be truncated to that amount of
        bytes
        r   )r   seekr   s     r   r   zLock._prepare_fhG  s1     = 	GGAJJJKKNNN	r   r`   )ra   rb   rc   __doc__r>   r?   LOCK_METHODFilenamer)   rg   rh   rd   rf   r   rz   rB   rk   rl   rD   rU   rR   r   r   r   r   r   r   r   r      s        . *. 6!9%0 1  1 1  1 '	 1
  1  1 " 1  1  1  1H +/1526	D D'D .D !/$/	D
 
6=	!D D D DL69V]3      
 
 
 
 
FI &)    fi FI      r   c            	            e Zd ZdZdeedef fd	Z	 	 	 ddej	        e
         dej	        e
         dej	        e         d	ej        f fd
Z fdZ xZS )RLockz
    A reentrant lock, functions in a similar way to threading.RLock in that it
    can be acquired multiple times.  When the corresponding number of release()
    calls are made the lock will finally release the underlying file lock.
    rs   Fc                 b    t                                          ||||||           d| _        d S )Nr   )superrB   _acquire_count)rA   r   r   r9   r:   r;   rt   	__class__s          r   rB   zRLock.__init__\  sC     		
 	
 	
  r   Nr9   r:   r;   r   c                     | j         dk    r| j        }n#t                                          |||          }| xj         dz  c_         |sJ |S )Nr   )r   r~   r   rD   )rA   r9   r:   r;   r~   r   s        r   rD   zRLock.acquireo  sX     !##BB.:JKKBq 				r   c                     | j         dk    rt          j        d          | j         dk    r t                                                       | xj         dz  c_         d S )Nr   z'Cannot release more times than acquiredr   )r   r   r   r   rR   )rA   r   s    r   rR   zRLock.release}  sg    !##*9   !##GGOOq r   r`   )ra   rb   rc   r   r=   r>   r   rB   rg   rh   rd   rf   rk   rD   rR   __classcell__r   s   @r   r   r   U  s          -           * +/1526	 ' . !/$/	
 
     ! ! ! ! ! ! ! ! !r   r   c                   &    e Zd ZdeedefdZd ZdS )TemporaryFileLockz.lockTc           	      z    t                               | |d||||           t          j        | j                   d S )Nr   )r   r   r9   r:   r;   rt   )r   rB   atexitregisterrR   )rA   r   r9   r:   r;   rt   s         r   rB   zTemporaryFileLock.__init__  sN     	)- 	 	
 	
 	
 	%%%%%r   c                     t                               |            t          j                            | j                  rt          j        | j                   d S d S r   )r   rR   r+   r5   isfiler   unlinkrQ   s    r   rR   zTemporaryFileLock.release  sN    T7>>$-(( 	%Idm$$$$$	% 	%r   N)ra   rb   rc   r=   r>   r   rB   rR   r   r   r   r   r     sH         -& & & &&% % % % %r   r   c                       e Zd ZU dZej        e         ed<   dd ej	                    e
edfdededed	ed
ej        e         dej        e         dej        e         f fdZdej        ej                 fdZdej        ej                 fdZdej        fdZ	 	 	 dd
ej        e         dej        e         dej        e         dej        e         fdZdej        e         defdZd Z xZS )BoundedSemaphorea0  
    Bounded semaphore to prevent too many parallel processes from running

    This method is deprecated because multiple processes that are completely
    unrelated could end up using the same semaphore.  To prevent this,
    use `NamedBoundedSemaphore` instead. The
    `NamedBoundedSemaphore` is a drop-in replacement for this class.

    >>> semaphore = BoundedSemaphore(2, directory='')
    >>> str(semaphore.get_filenames()[0])
    'bounded_semaphore.00.lock'
    >>> str(sorted(semaphore.get_random_filenames())[1])
    'bounded_semaphore.01.lock'
    r   bounded_semaphore{name}.{number:02d}.lockTmaximumr0   filename_pattern	directoryr9   r:   r;   c                     || _         || _        || _        || _        d | _        t                                          |||           |r|dk    rt          j        dt          d           d S d S )N)r9   r:   r;   r   z_`BoundedSemaphore` without an explicit `name` argument is deprecated, use NamedBoundedSemaphorer   rw   )
r   r0   r   r   r   r   rB   r|   r}   DeprecationWarning	rA   r   r0   r   r   r9   r:   r;   r   s	           r   rB   zBoundedSemaphore.__init__  s     	 0"+/	)- 	 	
 	
 	
  	t222MD"	      32r   r   c                 D      fdt           j                  D             S )Nc                 :    g | ]}                     |          S r   )get_filename)r   nrA   s     r   
<listcomp>z2BoundedSemaphore.get_filenames.<locals>.<listcomp>  s'    BBB!!!$$BBBr   )ranger   rQ   s   `r   get_filenameszBoundedSemaphore.get_filenames  s'    BBBBeDL.A.ABBBBr   c                 p    t          |                                           }t          j        |           |S r   )listr   randomshuffle)rA   	filenamess     r   get_random_filenamesz%BoundedSemaphore.get_random_filenames  s1    ++--..	y!!!r   c                 x    t          j        | j                  | j                            | j        |          z  S )N)r0   number)r"   r#   r   r   formatr0   )rA   r   s     r   r   zBoundedSemaphore.get_filename  s>    |DN++d.C.J.J /K /
 /
 
 	
r   Nc                 J   | j         r
J d            |                                 }|                     ||          D ]<}t                              d||           |                     |          r	| j         c S =t          || j                  x}rt          j	                    d S )NzAlready lockedztrying lock (attempt %d) %r)
r   r   rO   loggerdebugtry_lockr   r;   r   r   )rA   r9   r:   r;   r   r   s         r   rD   zBoundedSemaphore.acquire  s     9......&&((	((.AA 	! 	!ALL69EEE}}Y'' !y   !  (! 
  
 
 	- *,,,tr   r   c                    |D ]}t                               d|           t          |d          | _        	 | j                                         t                               d|            dS # t
          j        $ r
 d | _        Y w xY wdS )Nztrying lock for %rT)r;   z	locked %rF)r   r   r   r   rD   r   r   )rA   r   r   s      r   r   zBoundedSemaphore.try_lock  s    ! 		 		HLL-x888X===DI	!!### [(333tt	 + ! ! ! 			! us   A..BBc                 X    | j         "| j                                          d | _         d S d S r   )r   rR   rQ   s    r   rR   zBoundedSemaphore.release  s1    9 IDIII ! r   r`   )ra   rb   rc   r   rg   rh   r   re   r'   
gettempdirr=   r>   rn   r)   rd   rf   rB   Sequencer"   r#   r   r   r   rD   r   r   rR   r   r   s   @r   r   r     s          /$

 ( :,,..*91G26   	
  ' . !/$/     :Cvw|< C C C Cfogl&C    

gl 
 
 
 
 +/1526	 ' . !/$/	
 
	   0&/(";           r   r   c                        e Zd ZdZdd ej                    eedfdede	j
        e         deded	e	j
        e         d
e	j
        e         de	j
        e         f fdZ xZS )NamedBoundedSemaphorea  
    Bounded semaphore to prevent too many parallel processes from running

    It's also possible to specify a timeout when acquiring the lock to wait
    for a resource to become available.  This is very similar to
    `threading.BoundedSemaphore` but works across multiple processes and across
    multiple operating systems.

    Because this works across multiple processes it's important to give the
    semaphore a name.  This name is used to create the lock files.  If you
    don't specify a name, a random name will be generated.  This means that
    you can't use the same semaphore in multiple processes unless you pass the
    semaphore object to the other processes.

    >>> semaphore = NamedBoundedSemaphore(2, name='test')
    >>> str(semaphore.get_filenames()[0])
    '...test.00.lock'

    >>> semaphore = NamedBoundedSemaphore(2)
    >>> 'bounded_semaphore' in str(semaphore.get_filenames()[0])
    True

    Nr   Tr   r0   r   r   r9   r:   r;   c           	          |dt          j        dd          z  }t                                          |||||||           d S )Nzbounded_semaphore.%dr   i@B )r   randintr   rB   r   s	           r   rB   zNamedBoundedSemaphore.__init__%  s[     <)FN1g,F,FFD	
 	
 	
 	
 	
r   )ra   rb   rc   r   r'   r   r=   r>   rn   rg   rh   r)   rd   rf   rB   r   r   s   @r   r   r     s         6 &* :,,..*91G26
 

 oc"
 	

 
 '
 .
 !/$/
 
 
 
 
 
 
 
 
 
r   r   )T),ri   r   r1   loggingr+   r"   r   r'   rF   rg   r|    r   r   r   	getLoggerra   r   r=   r>   r?   rz   	EXCLUSIVEr{   r   __all__Unionr)   r#   r   rq   r   contextmanagerrf   rm   rk   r	   ABCr8   r   r   r   r   r   r   r   r   <module>r      s   



       				       0 0 0 0 0 0 0 0 0 0		8	$	$   !+i.A.NN 
 <W\)* :> F F FFJ FFJ F&* F F F F2  1$ 1$1$1$ _VY1$ 1$ 1$ 1$hA A A A Asw A A AHb b b b b8 b b bJ0! 0! 0! 0! 0!D 0! 0! 0!f% % % % % % % %4g g g g gx g g gT-
 -
 -
 -
 -
, -
 -
 -
 -
 -
r   