From 27602bf4e9da06e6d36e30836988316f3bdb3ebe Mon Sep 17 00:00:00 2001 From: nefrob Date: Tue, 26 Mar 2024 16:53:44 -0600 Subject: [PATCH 1/3] fix: raise error on incompatible singleton args --- src/filelock/_api.py | 12 ++++++++++-- tests/test_filelock.py | 11 +++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/filelock/_api.py b/src/filelock/_api.py index 49eaf1e4..8a35ab14 100644 --- a/src/filelock/_api.py +++ b/src/filelock/_api.py @@ -82,8 +82,8 @@ class BaseFileLock(ABC, contextlib.ContextDecorator): def __new__( # noqa: PLR0913 cls, lock_file: str | os.PathLike[str], - timeout: float = -1, # noqa: ARG003 - mode: int = 0o644, # noqa: ARG003 + timeout: float = -1, + mode: int = 0o644, thread_local: bool = True, # noqa: ARG003, FBT001, FBT002 *, is_singleton: bool = False, @@ -97,6 +97,9 @@ def __new__( # noqa: PLR0913 if not instance: instance = super().__new__(cls) cls._instances[str(lock_file)] = instance + elif timeout != instance.timeout or mode != instance.mode: + msg = "Singleton lock instances cannot be initialized with differing arguments" + raise ValueError(msg) return instance # type: ignore[return-value] # https://github.com/python/mypy/issues/15322 @@ -169,6 +172,11 @@ def timeout(self, value: float | str) -> None: """ self._context.timeout = float(value) + @property + def mode(self) -> int: + """:return: the file permissions for the lockfile""" + return self._context.mode + @abstractmethod def _acquire(self) -> None: """If the file lock could be acquired, self._context.lock_file_fd holds the file descriptor of the lock file.""" diff --git a/tests/test_filelock.py b/tests/test_filelock.py index 674d81a4..1fc8dc2c 100644 --- a/tests/test_filelock.py +++ b/tests/test_filelock.py @@ -675,6 +675,17 @@ def test_singleton_locks_are_distinct_per_lock_file(lock_type: type[BaseFileLock assert lock_1 is not lock_2 +@pytest.mark.parametrize("lock_type", [FileLock, SoftFileLock]) +def test_singleton_locks_must_be_initialized_with_the__same_args(lock_type: type[BaseFileLock], tmp_path: Path) -> None: + lock_path = tmp_path / "a" + lock = lock_type(str(lock_path), is_singleton=True) # noqa: F841 + + with pytest.raises(ValueError, match="Singleton lock instances cannot be initialized with differing arguments"): + lock_type(str(lock_path), timeout=10, is_singleton=True) + with pytest.raises(ValueError, match="Singleton lock instances cannot be initialized with differing arguments"): + lock_type(str(lock_path), mode=0, is_singleton=True) + + @pytest.mark.skipif(hasattr(sys, "pypy_version_info"), reason="del() does not trigger GC in PyPy") @pytest.mark.parametrize("lock_type", [FileLock, SoftFileLock]) def test_singleton_locks_are_deleted_when_no_external_references_exist( From 035af0518a48bca23d96e1b974c847011640edf9 Mon Sep 17 00:00:00 2001 From: nefrob Date: Tue, 26 Mar 2024 16:57:43 -0600 Subject: [PATCH 2/3] chore: remove extra underscore --- tests/test_filelock.py | 2 +- tox.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_filelock.py b/tests/test_filelock.py index 1fc8dc2c..a6be7003 100644 --- a/tests/test_filelock.py +++ b/tests/test_filelock.py @@ -676,7 +676,7 @@ def test_singleton_locks_are_distinct_per_lock_file(lock_type: type[BaseFileLock @pytest.mark.parametrize("lock_type", [FileLock, SoftFileLock]) -def test_singleton_locks_must_be_initialized_with_the__same_args(lock_type: type[BaseFileLock], tmp_path: Path) -> None: +def test_singleton_locks_must_be_initialized_with_the_same_args(lock_type: type[BaseFileLock], tmp_path: Path) -> None: lock_path = tmp_path / "a" lock = lock_type(str(lock_path), is_singleton=True) # noqa: F841 diff --git a/tox.ini b/tox.ini index cb6af212..0019c5e2 100644 --- a/tox.ini +++ b/tox.ini @@ -35,7 +35,7 @@ commands = [testenv:fix] description = format the code base to adhere to our styles, and complain about what we cannot do automatically -base_python = python3.10 +base_python = python3.12 skip_install = true deps = pre-commit>=3.5 From 1c7ad5bfbe5dd9416826eb4a681d52098e850e9e Mon Sep 17 00:00:00 2001 From: nefrob Date: Tue, 26 Mar 2024 16:59:25 -0600 Subject: [PATCH 3/3] chore: revert tox file change --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 0019c5e2..cb6af212 100644 --- a/tox.ini +++ b/tox.ini @@ -35,7 +35,7 @@ commands = [testenv:fix] description = format the code base to adhere to our styles, and complain about what we cannot do automatically -base_python = python3.12 +base_python = python3.10 skip_install = true deps = pre-commit>=3.5