From d0b2c34ebd36b9c0ab8f4974ebe2aae00484e062 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 c172d935b1a..4d58dc6c5ac 100644 --- a/poetry.lock +++ b/poetry.lock @@ -956,7 +956,7 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>= [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "aab6953ba157fa41e2404572602a0ed1a3d1477e119892753b1551e999c26d37" +content-hash = "d7707db625aeb5cc2bb8895e48927b86e443ba7c5ef83249b470f4b69b969931" [metadata.files] attrs = [ diff --git a/pyproject.toml b/pyproject.toml index 9110031cb14..e3aeb9ba577 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.46" +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.46" [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..937987231aa 100644 --- a/src/poetry/utils/authenticator.py +++ b/src/poetry/utils/authenticator.py @@ -12,12 +12,14 @@ from typing import TYPE_CHECKING from typing import Any +import lockfile import requests import requests.auth import requests.exceptions from cachecontrol import CacheControl from cachecontrol.caches import FileCache +from filelock import FileLock from poetry.config.config import Config from poetry.exceptions import PoetryException @@ -33,6 +35,26 @@ logger = logging.getLogger(__name__) +class BetterLockFile(lockfile.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