From 7cdcf2757624f3960893b0480396f62c4df60a89 Mon Sep 17 00:00:00 2001 From: David Hotham Date: Sat, 10 Sep 2022 15:38:39 +0100 Subject: [PATCH] Use filelock to lock the file cache --- poetry.lock | 2 +- pyproject.toml | 4 +++- src/poetry/utils/authenticator.py | 25 ++++++++++++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 35e64522660..519dc03d6ee 100644 --- a/poetry.lock +++ b/poetry.lock @@ -939,7 +939,7 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>= [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "7e40cde2399843d53e715f657b703397ce236196663788ada896d7e2a53c869a" +content-hash = "85f5c44c57fc902b0cd784adad949d1708665aa34168e6ae93ebf6cb40aae6c5" [metadata.files] atomicwrites = [ diff --git a/pyproject.toml b/pyproject.toml index 8d95d3811c6..4bb6f1e83c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,8 @@ cachecontrol = { version = "^0.12.9", extras = ["filecache"] } cachy = "^0.3.0" cleo = "^1.0.0a5" crashtest = "^0.3.0" +dulwich = "^0.20.44" +filelock = "^3.8.0" html5lib = "^1.0" importlib-metadata = { version = "^4.4", python = "<3.10" } jsonschema = "^4.10.0" @@ -70,7 +72,6 @@ tomlkit = ">=0.11.1,<1.0.0,!=0.11.2,!=0.11.3" virtualenv = ">=20.4.3,!=20.4.5,!=20.4.6" xattr = { version = "^0.9.7", markers = "sys_platform == 'darwin'" } urllib3 = "^1.26.0" -dulwich = "^0.20.44" [tool.poetry.group.dev.dependencies] pytest = "^7.1" @@ -155,6 +156,7 @@ module = [ 'cachy.*', 'cleo.*', 'crashtest.*', + 'lockfile.*', 'pexpect.*', 'pkginfo.*', 'requests_toolbelt.*', diff --git a/src/poetry/utils/authenticator.py b/src/poetry/utils/authenticator.py index 8e5239cd5c2..5e245b3befa 100644 --- a/src/poetry/utils/authenticator.py +++ b/src/poetry/utils/authenticator.py @@ -18,6 +18,8 @@ from cachecontrol import CacheControl from cachecontrol.caches import FileCache +from filelock import FileLock +from lockfile import LockBase from poetry.config.config import Config from poetry.exceptions import PoetryException @@ -33,6 +35,26 @@ logger = logging.getLogger(__name__) +class BetterLockFile(LockBase): # type: ignore[misc] + # The default LockFile from the lockfile package as used by cachecontrol can remain + # locked if a process exits ungracefully. See eg + # . + # + # FileLock from the filelock package does not have this problem, so we use that to + # construct something compatible with cachecontrol. + def __init__( + self, path: str, threaded: bool = True, timeout: float | None = None + ) -> None: + super().__init__(path, threaded, timeout) + self.file_lock = FileLock(self.lock_file) + + def acquire(self, timeout: float | None = None) -> None: + self.file_lock.acquire(timeout=timeout) + + def release(self) -> None: + self.file_lock.release() + + @dataclasses.dataclass(frozen=True) class RepositoryCertificateConfig: cert: Path | None = dataclasses.field(default=None) @@ -122,7 +144,8 @@ def __init__( self._config.repository_cache_directory / (cache_id or "_default_cache") / "_http" - ) + ), + lock_class=BetterLockFile, ) if not disable_cache else None