ÿØÿà JFIF    ÿÛ „ ( %!1!%*+...983,7(-.- PK:G]'m;;__pycache__/_api.cpython-37.pycnu[B a @sddlmZddlZddlZddlZddlZddlmZmZddl m Z ddl m Z ddl mZddlmZed ZGd d d ZGd d d eZd d gZdS)) annotationsN)ABCabstractmethod)Lock) TracebackType)Any)TimeoutZfilelockc@sBeZdZdZdddddZdddd Zd d d dd ddZdS)AcquireReturnProxyzDA context aware object that will release the lock file when exiting. BaseFileLockNone)lockreturncCs ||_dS)N)r )selfr r>/opt/alt/python37/lib/python3.7/site-packages/filelock/_api.py__init__szAcquireReturnProxy.__init__)rcCs|jS)N)r )rrrr __enter__szAcquireReturnProxy.__enter__ztype[BaseException] | NonezBaseException | NonezTracebackType | None)exc_type exc_value tracebackrcCs|jdS)N)r release)rrrrrrr__exit__szAcquireReturnProxy.__exit__N)__name__ __module__ __qualname____doc__rrrrrrrr sr c@seZdZdZd/ddddddZed d d d Zedd d dZejdddddZe dd ddZ e dd ddZ edd ddZ d0ddddddddd Z d1ddd"d#d$Zdd d%d&Zd'd(d)dd*d+d,Zdd d-d.ZdS)2r z+Abstract base class for a file lock object.zstr | os.PathLike[Any]floatr ) lock_filetimeoutrcCs*t||_d|_||_t|_d|_dS)a Create a new lock object. :param lock_file: path to the file :param timeout: default timeout when acquiring the lock. 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)osfspath _lock_file _lock_file_fdr r _thread_lock _lock_counter)rrr rrrr)s zBaseFileLock.__init__str)rcCs|jS)z:return: path to the lock file)r#)rrrrrCszBaseFileLock.lock_filecCs|jS)zU :return: the default timeout value .. versionadded:: 2.0.0 )_timeout)rrrrr HszBaseFileLock.timeoutz float | str)valuercCst||_dS)zX Change the default timeout value. :param value: the new value N)rr()rr)rrrr QscCstdS)zbIf the file lock could be acquired, self._lock_file_fd holds the file descriptor of the lock file.N)NotImplementedError)rrrr_acquireZszBaseFileLock._acquirecCstdS)z6Releases the lock and sets self._lock_file_fd to None.N)r*)rrrr_release_szBaseFileLock._releaseboolcCs |jdk 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$)rrrr is_lockedds zBaseFileLock.is_lockedN皙?)poll_intervallz float | Noner )r poll_intervalr0rc CsT|dkr|j}|dk r.d}tj|tdd|}|j|jd7_WdQRXt|}|j}t}yx|j"|j st d||| WdQRX|j rt d||Pqhd|krt|krnnt d ||t |jqhd }t ||||t|qhWWn<tk rH|jtd|jd|_WdQRXYnXt|d S) az 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 :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) stacklevelrz#Attempting to acquire lock %s on %szLock %s acquired on %srz"Timeout on acquiring lock %s on %sz2Lock %s not acquired on %s, waiting %s seconds ...)r )r warningswarnDeprecationWarningr%r&idr#timer._LOGGERdebugr+r sleep BaseExceptionmaxr )rr r1r0msglock_id lock_filenameZ start_timerrracquireps>%  zBaseFileLock.acquireF)forcerc Csr|jb|jrd|jd8_|jdks*|rdt||j}}td|||d|_td||WdQRXdS)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/ rrz#Attempting to release lock %s on %szLock %s released on %sN)r%r.r&r7r#r9r:r,)rrBr?r@rrrrszBaseFileLock.releasecCs ||S)zE Acquire the lock. :return: the lock object )rA)rrrrrszBaseFileLock.__enter__ztype[BaseException] | NonezBaseException | NonezTracebackType | None)rrrrcCs |dS)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)rrrrrrrrs zBaseFileLock.__exit__cCs|jdddS)z'Called when the lock object is deleted.T)rBN)r)rrrr__del__szBaseFileLock.__del__)r)Nr/)F)rrrrrpropertyrr setterrr+r,r.rArrrrCrrrrr &s  F r ) __future__rloggingr!r8r4abcrr threadingrtypesrtypingr_errorr getLoggerr9r r __all__rrrrs      HPK:G](w"__pycache__/version.cpython-37.pycnu[B a@s dZdZdS)z3.4.2)N)versionZ version_tuplerrA/opt/alt/python37/lib/python3.7/site-packages/filelock/version.pysPK:G]j __pycache__/_unix.cpython-37.pycnu[B a@sddlmZddlZddlZddlmZddlmZddlm Z dZ ej dkrbGd d d e eZ n6y ddl Z Wnek rYnXd Z Gd d d e Z d d gZdS)) annotationsN)ABC)cast) BaseFileLockFwin32c@seZdZdZdS) UnixFileLockzHUses the :func:`fcntl.flock` to hard lock the lock file on unix systems.N)__name__ __module__ __qualname____doc__r r ?/opt/alt/python37/lib/python3.7/site-packages/filelock/_unix.pyrsrTc@s,eZdZdZddddZddddZdS) rzHUses the :func:`fcntl.flock` to hard lock the lock file on unix systems.None)returncCsbtjtjBtjB}t|j|}yt|tjtj BWnt k rVt |YnX||_ dS)N) osO_RDWRO_CREATO_TRUNCopenZ _lock_filefcntlflockZLOCK_EXZLOCK_NBOSErrorclose _lock_file_fd)selfZ open_modefdr r r_acquireszUnixFileLock._acquirecCs.tt|j}d|_t|tjt|dS)N)rintrrrZLOCK_UNrr)rrr r r_release&s zUnixFileLock._releaseN)r r r r rrr r r rrs has_fcntl) __future__rrsysabcrtypingrZ_apirr platformrr ImportError__all__r r r rs      PK:G]>H#__pycache__/_windows.cpython-37.pycnu[B a@sddlmZddlZddlZddlmZddlmZddlm Z ddl m Z ddl m Z ejd kr|ddlZGd d d e ZnGd d d e eZd gZdS) ) annotationsN)ABC)ENOENT)cast) BaseFileLock)raise_on_exist_ro_filewin32c@s,eZdZdZddddZddddZdS) WindowsFileLockzWUses the :func:`msvcrt.locking` function to hard lock the lock file on windows systems.None)returnc Cst|jtjtjBtjB}yt|j|}Wn.tk r\}z|jt krLWdd}~XYns       %PK:G]^O#__pycache__/__init__.cpython-37.pycnu[B a@sUdZddlmZddlZddlZddlmZmZddlm Z ddl m Z ddl m Z mZdd lmZdd lmZeZd ed <ejd kreZded<n(ere Zded<ne Zedk redeZded<d dddddddgZdS)zw A platform independent file lock that supports the with-statement. .. autodata:: filelock.__version__ :no-value: ) annotationsN)AcquireReturnProxy BaseFileLock)Timeout) SoftFileLock) UnixFileLock has_fcntl)WindowsFileLock)versionstr __version__win32ztype[BaseFileLock] _FileLockz only soft file lock is availableFileLockrrrr rr)__doc__ __future__rsyswarningsZ_apirr_errorrZ_softrZ_unixrr Z_windowsr r r __annotations__platformrwarnr__all__rrB/opt/alt/python37/lib/python3.7/site-packages/filelock/__init__.pys4         PK:G]CC __pycache__/_util.cpython-37.pycnu[B aR@s6ddlmZddlZddlZdddddZdgZdS)) annotationsNstrNone)filenamereturncCsLyt|}Wntk r"dSX|jdkrH|jtj@sHtd|dS)NrzPermission denied: )osstatOSErrorst_mtimest_modeS_IWUSRPermissionError)rZ file_statr?/opt/alt/python37/lib/python3.7/site-packages/filelock/_util.pyraise_on_exist_ro_files  r) __future__rrrr__all__rrrrs  PK:G] 4 __pycache__/_soft.cpython-37.pycnu[B ar@sbddlmZddlZddlZddlmZmZmZddlm Z ddl m Z Gddde Z dgZ dS) ) annotationsN)EACCESEEXISTENOENT) BaseFileLock)raise_on_exist_ro_filec@s,eZdZdZddddZddddZdS) SoftFileLockz.Simply watches the existence of the lock file.None)returnc Cst|jtjtjBtjBtjB}yt|j|}WnRtk r}z4|j t krRn$|j t kr`n|j t krvt jdkrvWdd}~XYnX||_dS)Nwin32)r _lock_fileosO_WRONLYO_CREATO_EXCLO_TRUNCopenOSErrorerrnorrrsysplatform _lock_file_fd)selfmodefd exceptionr?/opt/alt/python37/lib/python3.7/site-packages/filelock/_soft.py_acquires   zSoftFileLock._acquirecCs<t|jd|_yt|jWntk r6YnXdS)N)rcloserremover r)rrrr_release$s  zSoftFileLock._releaseN)__name__ __module__ __qualname____doc__rr"rrrrr sr ) __future__rrrrrrrZ_apirZ_utilrr __all__rrrrs   #PK:G]N''!__pycache__/_error.cpython-37.pycnu[B a@s&ddlmZGdddeZdgZdS)) annotationsc@s.eZdZdZdddddZdddd Zd S) Timeoutz@Raised when the lock could not be acquired in *timeout* seconds.strNone) lock_filereturncCs ||_dS)N)r)selfrr @/opt/alt/python37/lib/python3.7/site-packages/filelock/_error.py__init__szTimeout.__init__)rcCsd|jdS)NzThe file lock 'z' could not be acquired.)r)rr r r __str__ szTimeout.__str__N)__name__ __module__ __qualname____doc__r r r r r r rsrN) __future__r TimeoutErrorr__all__r r r r s  PK:G]g _error.pynu[from __future__ import annotations class Timeout(TimeoutError): """Raised when the lock could not be acquired in *timeout* seconds.""" def __init__(self, lock_file: str) -> None: #: The path of the file lock. self.lock_file = lock_file def __str__(self) -> str: return f"The file lock '{self.lock_file}' could not be acquired." __all__ = [ "Timeout", ] PK:G]tT4 version.pynu[# coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control version = '3.4.2' version_tuple = (3, 4, 2) PK:G]py.typednu[PK:G]nc9 _api.pynu[from __future__ import annotations import logging import os import time import warnings from abc import ABC, abstractmethod from threading import Lock from types import TracebackType from typing import Any from ._error import Timeout _LOGGER = logging.getLogger("filelock") # This is a helper class which is returned by :meth:`BaseFileLock.acquire` and wraps the lock to make sure __enter__ # is not called twice when entering the with statement. If we would simply return *self*, the lock would be acquired # again in the *__enter__* method of the BaseFileLock, but not released again automatically. issue #37 (memory leak) class AcquireReturnProxy: """A context aware object that will release the lock file when exiting.""" def __init__(self, lock: BaseFileLock) -> None: self.lock = lock def __enter__(self) -> BaseFileLock: return self.lock def __exit__( self, exc_type: type[BaseException] | None, # noqa: U100 exc_value: BaseException | None, # noqa: U100 traceback: TracebackType | None, # noqa: U100 ) -> None: self.lock.release() class BaseFileLock(ABC): """Abstract base class for a file lock object.""" def __init__(self, lock_file: str | os.PathLike[Any], timeout: float = -1) -> None: """ Create a new lock object. :param lock_file: path to the file :param timeout: default timeout when acquiring the lock. 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. """ # The path to the lock file. self._lock_file: str = os.fspath(lock_file) # The file descriptor for the *_lock_file* as it is returned by the os.open() function. # This file lock is only NOT None, if the object currently holds the lock. self._lock_file_fd: int | None = None # The default timeout value. self.timeout: float = timeout # We use this lock primarily for the lock counter. self._thread_lock: Lock = Lock() # The lock counter is used for implementing the nested locking mechanism. Whenever the lock is acquired, the # counter is increased and the lock is only released, when this value is 0 again. self._lock_counter: int = 0 @property def lock_file(self) -> str: """:return: path to the lock file""" return self._lock_file @property def timeout(self) -> float: """ :return: the default timeout value .. versionadded:: 2.0.0 """ return self._timeout @timeout.setter def timeout(self, value: float | str) -> None: """ Change the default timeout value. :param value: the new value """ self._timeout = float(value) @abstractmethod def _acquire(self) -> None: """If the file lock could be acquired, self._lock_file_fd holds the file descriptor of the lock file.""" raise NotImplementedError @abstractmethod def _release(self) -> None: """Releases the lock and sets self._lock_file_fd to None.""" raise NotImplementedError @property def is_locked(self) -> bool: """ :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. """ return self._lock_file_fd is not None def acquire( self, timeout: float | None = None, poll_interval: float = 0.05, *, poll_intervall: float | None = None, ) -> AcquireReturnProxy: """ 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 :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. """ # Use the default timeout, if no timeout is provided. if timeout is None: timeout = self.timeout if poll_intervall is not None: msg = "use poll_interval instead of poll_intervall" warnings.warn(msg, DeprecationWarning, stacklevel=2) poll_interval = poll_intervall # Increment the number right at the beginning. We can still undo it, if something fails. with self._thread_lock: self._lock_counter += 1 lock_id = id(self) lock_filename = self._lock_file start_time = time.time() try: while True: with self._thread_lock: if not self.is_locked: _LOGGER.debug("Attempting to acquire lock %s on %s", lock_id, lock_filename) self._acquire() if self.is_locked: _LOGGER.debug("Lock %s acquired on %s", lock_id, lock_filename) break elif 0 <= timeout < time.time() - start_time: _LOGGER.debug("Timeout on acquiring lock %s on %s", lock_id, lock_filename) raise Timeout(self._lock_file) else: msg = "Lock %s not acquired on %s, waiting %s seconds ..." _LOGGER.debug(msg, lock_id, lock_filename, poll_interval) time.sleep(poll_interval) except BaseException: # Something did go wrong, so decrement the counter. with self._thread_lock: self._lock_counter = max(0, self._lock_counter - 1) raise return AcquireReturnProxy(lock=self) def release(self, force: bool = False) -> None: """ 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/ """ with self._thread_lock: if self.is_locked: self._lock_counter -= 1 if self._lock_counter == 0 or force: lock_id, lock_filename = id(self), self._lock_file _LOGGER.debug("Attempting to release lock %s on %s", lock_id, lock_filename) self._release() self._lock_counter = 0 _LOGGER.debug("Lock %s released on %s", lock_id, lock_filename) def __enter__(self) -> BaseFileLock: """ Acquire the lock. :return: the lock object """ self.acquire() return self def __exit__( self, exc_type: type[BaseException] | None, # noqa: U100 exc_value: BaseException | None, # noqa: U100 traceback: TracebackType | None, # noqa: U100 ) -> None: """ 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 """ self.release() def __del__(self) -> None: """Called when the lock object is deleted.""" self.release(force=True) __all__ = [ "BaseFileLock", "AcquireReturnProxy", ] PK:G].j _windows.pynu[from __future__ import annotations import os import sys from abc import ABC from errno import ENOENT from typing import cast from ._api import BaseFileLock from ._util import raise_on_exist_ro_file if sys.platform == "win32": # pragma: win32 cover import msvcrt class WindowsFileLock(BaseFileLock): """Uses the :func:`msvcrt.locking` function to hard lock the lock file on windows systems.""" def _acquire(self) -> None: raise_on_exist_ro_file(self._lock_file) mode = ( os.O_RDWR # open for read and write | os.O_CREAT # create file if not exists | os.O_TRUNC # truncate file if not empty ) try: fd = os.open(self._lock_file, mode) except OSError as exception: if exception.errno == ENOENT: # No such file or directory raise else: try: msvcrt.locking(fd, msvcrt.LK_NBLCK, 1) except OSError: os.close(fd) else: self._lock_file_fd = fd def _release(self) -> None: fd = cast(int, self._lock_file_fd) self._lock_file_fd = None msvcrt.locking(fd, msvcrt.LK_UNLCK, 1) os.close(fd) try: os.remove(self._lock_file) # Probably another instance of the application hat acquired the file lock. except OSError: pass else: # pragma: win32 no cover class WindowsFileLock(BaseFileLock, ABC): """Uses the :func:`msvcrt.locking` function to hard lock the lock file on windows systems.""" __all__ = [ "WindowsFileLock", ] PK:G]sRR_util.pynu[from __future__ import annotations import os import stat def raise_on_exist_ro_file(filename: str) -> None: try: file_stat = os.stat(filename) # use stat to do exists + can write to check without race condition except OSError: return None # swallow does not exist or other errors if file_stat.st_mtime != 0: # if os.stat returns but modification is zero that's an invalid os.stat - ignore it if not (file_stat.st_mode & stat.S_IWUSR): raise PermissionError(f"Permission denied: {filename!r}") __all__ = [ "raise_on_exist_ro_file", ] PK:G]9_unix.pynu[from __future__ import annotations import os import sys from abc import ABC from typing import cast from ._api import BaseFileLock #: a flag to indicate if the fcntl API is available has_fcntl = False if sys.platform == "win32": # pragma: win32 cover class UnixFileLock(BaseFileLock, ABC): """Uses the :func:`fcntl.flock` to hard lock the lock file on unix systems.""" else: # pragma: win32 no cover try: import fcntl except ImportError: pass else: has_fcntl = True class UnixFileLock(BaseFileLock): """Uses the :func:`fcntl.flock` to hard lock the lock file on unix systems.""" def _acquire(self) -> None: open_mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC fd = os.open(self._lock_file, open_mode) try: fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) except OSError: os.close(fd) else: self._lock_file_fd = fd def _release(self) -> None: # Do not remove the lockfile: # https://github.com/tox-dev/py-filelock/issues/31 # https://stackoverflow.com/questions/17708885/flock-removing-locked-file-without-race-condition fd = cast(int, self._lock_file_fd) self._lock_file_fd = None fcntl.flock(fd, fcntl.LOCK_UN) os.close(fd) __all__ = [ "has_fcntl", "UnixFileLock", ] PK:G]c __init__.pynu[""" A platform independent file lock that supports the with-statement. .. autodata:: filelock.__version__ :no-value: """ from __future__ import annotations import sys import warnings from ._api import AcquireReturnProxy, BaseFileLock from ._error import Timeout from ._soft import SoftFileLock from ._unix import UnixFileLock, has_fcntl from ._windows import WindowsFileLock from .version import version #: version of the project as a string __version__: str = version if sys.platform == "win32": # pragma: win32 cover _FileLock: type[BaseFileLock] = WindowsFileLock else: # pragma: win32 no cover if has_fcntl: _FileLock: type[BaseFileLock] = UnixFileLock else: _FileLock = SoftFileLock if warnings is not None: warnings.warn("only soft file lock is available") #: Alias for the lock, which should be used for the current platform. On Windows, this is an alias for # :class:`WindowsFileLock`, on Unix for :class:`UnixFileLock` and otherwise for :class:`SoftFileLock`. FileLock: type[BaseFileLock] = _FileLock __all__ = [ "__version__", "FileLock", "SoftFileLock", "Timeout", "UnixFileLock", "WindowsFileLock", "BaseFileLock", "AcquireReturnProxy", ] PK:G]0?Nrr_soft.pynu[from __future__ import annotations import os import sys from errno import EACCES, EEXIST, ENOENT from ._api import BaseFileLock from ._util import raise_on_exist_ro_file class SoftFileLock(BaseFileLock): """Simply watches the existence of the lock file.""" def _acquire(self) -> None: raise_on_exist_ro_file(self._lock_file) # first check for exists and read-only mode as the open will mask this case as EEXIST mode = ( os.O_WRONLY # open for writing only | os.O_CREAT | os.O_EXCL # together with above raise EEXIST if the file specified by filename exists | os.O_TRUNC # truncate the file to zero byte ) try: fd = os.open(self._lock_file, mode) except OSError as exception: if exception.errno == EEXIST: # expected if cannot lock pass elif exception.errno == ENOENT: # No such file or directory - parent directory is missing raise elif exception.errno == EACCES and sys.platform != "win32": # pragma: win32 no cover # Permission denied - parent dir is R/O raise # note windows does not allow you to make a folder r/o only files else: self._lock_file_fd = fd def _release(self) -> None: os.close(self._lock_file_fd) # type: ignore # the lock file is definitely not None self._lock_file_fd = None try: os.remove(self._lock_file) except OSError: # the file is already deleted and that's what we want pass __all__ = [ "SoftFileLock", ] PK:G]'m;;__pycache__/_api.cpython-37.pycnu[PK:G](w"__pycache__/version.cpython-37.pycnu[PK:G]j __pycache__/_unix.cpython-37.pycnu[PK:G]>H#$__pycache__/_windows.cpython-37.pycnu[PK:G]^O#+__pycache__/__init__.cpython-37.pycnu[PK:G]CC 10__pycache__/_util.cpython-37.pycnu[PK:G] 4 2__pycache__/_soft.cpython-37.pycnu[PK:G]N''!-8__pycache__/_error.cpython-37.pycnu[PK:G]g ;_error.pynu[PK:G]tT4 m=version.pynu[PK:G]5>py.typednu[PK:G]nc9 m>_api.pynu[PK:G].j @__windows.pynu[PK:G]sRR`f_util.pynu[PK:G]9h_unix.pynu[PK:G]c n__init__.pynu[PK:G]0?Nrrs_soft.pynu[PKz