U
    "c"                     @  s   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mZm	Z	 d dl
mZ d dlmZ d dlmZ ddlmZ ed	ZG d
d dZG dd deejZddgZdS )    )annotationsN)ABCabstractmethod)Lock)TracebackType)Any   )TimeoutZfilelockc                   @  sB   e Zd ZdZdddddZdddd	Zd
ddddddZdS )AcquireReturnProxyzDA context aware object that will release the lock file when exiting.BaseFileLockNone)lockreturnc                 C  s
   || _ d S Nr   )selfr    r   1/tmp/pip-unpacked-wheel-yt0gy6q2/filelock/_api.py__init__   s    zAcquireReturnProxy.__init__r   c                 C  s   | j S r   r   r   r   r   r   	__enter__   s    zAcquireReturnProxy.__enter__type[BaseException] | NoneBaseException | NoneTracebackType | Noneexc_type	exc_value	tracebackr   c                 C  s   | j   d S r   )r   releaser   r   r   r   r   r   r   __exit__   s    zAcquireReturnProxy.__exit__N)__name__
__module____qualname____doc__r   r   r!   r   r   r   r   r
      s   r
   c                   @  s   e Zd ZdZd0ddddddZed	d
ddZedd
ddZejdddddZe	dd
ddZ
e	dd
ddZedd
ddZd1dddddddddd d!Zd2ddd#d$d%Zd d
d&d'Zd(d)d*dd+d,d-Zdd
d.d/ZdS )3r   z+Abstract base class for a file lock object.zstr | os.PathLike[Any]floatr   )	lock_filetimeoutr   c                 C  s*   t || _d| _|| _t | _d| _dS )a  
        Create a new lock object.

        :param lock_file: path to the file
        :param timeout: default timeout when acquiring the lock, in seconds. It will be used as fallback value in
        the acquire method, if no timeout value (``None``) is given. If you want to disable the timeout, set it
        to a negative value. A timeout of 0 means, that there is exactly one attempt to acquire the file lock.
        Nr   )osfspath
_lock_file_lock_file_fd_timeoutr   _thread_lock_lock_counter)r   r(   r)   r   r   r   r   *   s
    
zBaseFileLock.__init__strr   c                 C  s   | j S )z:return: path to the lock file)r,   r   r   r   r   r(   D   s    zBaseFileLock.lock_filec                 C  s   | j S )za
        :return: the default timeout value, in seconds

        .. versionadded:: 2.0.0
        )r.   r   r   r   r   r)   I   s    zBaseFileLock.timeoutzfloat | str)valuer   c                 C  s   t || _dS )zd
        Change the default timeout value.

        :param value: the new value, in seconds
        N)r'   r.   )r   r2   r   r   r   r)   R   s    c                 C  s   t dS )zbIf the file lock could be acquired, self._lock_file_fd holds the file descriptor of the lock file.NNotImplementedErrorr   r   r   r   _acquire[   s    zBaseFileLock._acquirec                 C  s   t dS )z6Releases the lock and sets self._lock_file_fd to None.Nr3   r   r   r   r   _release`   s    zBaseFileLock._releaseboolc                 C  s
   | j dk	S )z

        :return: A boolean indicating if the lock file is holding the lock currently.

        .. versionchanged:: 2.0.0

            This was previously a method and is now a property.
        N)r-   r   r   r   r   	is_lockede   s    
zBaseFileLock.is_lockedN皙?T)poll_intervallblockingzfloat | Noner
   )r)   poll_intervalr:   r;   r   c          	      C  sv  |dkr| j }|dk	r.d}tj|tdd |}| j |  jd7  _W 5 Q R X t| }| j}t	 }z| j" | j
std|| |   W 5 Q R X | j
rtd|| q,qf|dkrtd	|| t| jqfd
|  krt	 | k rn ntd|| t| jqfd}t|||| t| qfW n< tk
rj   | j td
| jd | _W 5 Q R X  Y nX t| dS )a^  
        Try to acquire the file lock.

        :param timeout: maximum wait time for acquiring the lock, ``None`` means use the default :attr:`~timeout` is and
         if ``timeout < 0``, there is no timeout and this method will block until the lock could be acquired
        :param poll_interval: interval of trying to acquire the lock file
        :param poll_intervall: deprecated, kept for backwards compatibility, use ``poll_interval`` instead
        :param blocking: defaults to True. If False, function will return immediately if it cannot obtain a lock on the
         first attempt. Otherwise this method will block until the timeout expires or the lock is acquired.
        :raises Timeout: if fails to acquire lock within the timeout period
        :return: a context object that will unlock the file when the context is exited

        .. code-block:: python

            # You can use this method in the context manager (recommended)
            with lock.acquire():
                pass

            # Or use an equivalent try-finally construct:
            lock.acquire()
            try:
                pass
            finally:
                lock.release()

        .. versionchanged:: 2.0.0

            This method returns now a *proxy* object instead of *self*,
            so that it can be used in a with statement without side effects.

        Nz+use poll_interval instead of poll_intervall   )
stacklevelr   z#Attempting to acquire lock %s on %szLock %s acquired on %sFz+Failed to immediately acquire lock %s on %sr   z"Timeout on acquiring lock %s on %sz2Lock %s not acquired on %s, waiting %s seconds ...r   )r)   warningswarnDeprecationWarningr/   r0   idr,   time	monotonicr8   _LOGGERdebugr5   r	   sleepBaseExceptionmaxr
   )	r   r)   r<   r:   r;   msglock_idlock_filename
start_timer   r   r   acquireq   sB    ("zBaseFileLock.acquireF)forcer   c              	   C  sr   | j b | jrd|  jd8  _| jdks*|rdt| | j }}td|| |   d| _td|| W 5 Q R X dS )a*  
        Releases the file lock. Please note, that the lock is only completely released, if the lock counter is 0. Also
        note, that the lock file itself is not automatically deleted.

        :param force: If true, the lock counter is ignored and the lock is released in every case/
        r   r   z#Attempting to release lock %s on %szLock %s released on %sN)r/   r8   r0   rB   r,   rE   rF   r6   )r   rO   rK   rL   r   r   r   r      s    zBaseFileLock.releasec                 C  s   |    | S )zE
        Acquire the lock.

        :return: the lock object
        )rN   r   r   r   r   r      s    zBaseFileLock.__enter__r   r   r   r   c                 C  s   |    dS )z
        Release the lock.

        :param exc_type: the exception type if raised
        :param exc_value: the exception value if raised
        :param traceback: the exception traceback if raised
        Nr   r    r   r   r   r!      s    zBaseFileLock.__exit__c                 C  s   | j dd dS )z'Called when the lock object is deleted.T)rO   NrP   r   r   r   r   __del__   s    zBaseFileLock.__del__)r&   )Nr9   )F)r"   r#   r$   r%   r   propertyr(   r)   setterr   r5   r6   r8   rN   r   r   r!   rQ   r   r   r   r   r   '   s0     Q	r   )
__future__r   
contextlibloggingr*   rC   r?   abcr   r   	threadingr   typesr   typingr   _errorr	   	getLoggerrE   r
   ContextDecoratorr   __all__r   r   r   r   <module>   s"   
 N