From fcb4e217a3f9568e42b105d8aa28f50eac8cc2b6 Mon Sep 17 00:00:00 2001 From: Hirsch Alter Date: Mon, 3 Jan 2022 16:53:48 +0200 Subject: [PATCH 1/5] Enable use as a context decorator (#127) --- docs/changelog.rst | 4 ++++ src/filelock/_api.py | 3 ++- tests/test_filelock.py | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index acd9c56..095acec 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,10 @@ Changelog ========= +v3.5.0 (2022-01-03) +------------------- +- Enable use as context decorator + v3.4.2 (2021-12-16) ------------------- - Drop support for python ``3.6`` diff --git a/src/filelock/_api.py b/src/filelock/_api.py index 3551d5d..d3cffc4 100644 --- a/src/filelock/_api.py +++ b/src/filelock/_api.py @@ -1,5 +1,6 @@ from __future__ import annotations +import contextlib import logging import os import time @@ -35,7 +36,7 @@ def __exit__( self.lock.release() -class BaseFileLock(ABC): +class BaseFileLock(ABC, contextlib.ContextDecorator): """Abstract base class for a file lock object.""" def __init__(self, lock_file: str | os.PathLike[Any], timeout: float = -1) -> None: diff --git a/tests/test_filelock.py b/tests/test_filelock.py index 6991137..99b2920 100644 --- a/tests/test_filelock.py +++ b/tests/test_filelock.py @@ -368,3 +368,17 @@ def test_poll_intervall_deprecated(lock_type: type[BaseFileLock], tmp_path: Path break else: # pragma: no cover pytest.fail("No warnings of stacklevel=2 matching.") + + +@pytest.mark.parametrize("lock_type", [FileLock, SoftFileLock]) +def test_context_decorator(lock_type: type[BaseFileLock], tmp_path: Path) -> None: + lock_path = tmp_path / "a" + lock = lock_type(str(lock_path)) + + @lock + def decorated_method(): + assert lock.is_locked + + assert not lock.is_locked + decorated_method() + assert not lock.is_locked From 869d1291f266c8de662cb1618f8a09a0d11aea0a Mon Sep 17 00:00:00 2001 From: Hirsch Alter Date: Mon, 3 Jan 2022 17:01:38 +0200 Subject: [PATCH 2/5] Enable use as a context decorator (documentation) (#127) --- docs/index.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index bc95510..b6b2cf4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -67,6 +67,12 @@ locks: finally: lock.release() + @lock + def decorated(): + open(file_path, "a").write("You're a decorated Jedi!") + + decorated() + The :meth:`acquire ` method accepts also a ``timeout`` parameter. If the lock cannot be acquired within ``timeout`` seconds, a :class:`Timeout ` exception is raised: From 459f81e04675e8ef75a0a20a79b67734291e2c79 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Jan 2022 15:01:53 +0000 Subject: [PATCH 3/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- docs/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index b6b2cf4..072aa01 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -67,10 +67,12 @@ locks: finally: lock.release() + @lock def decorated(): open(file_path, "a").write("You're a decorated Jedi!") + decorated() The :meth:`acquire ` method accepts also a ``timeout`` parameter. If the lock cannot be From dc0d82c9ded3bad76430f34c48ae8b60ef9e7be2 Mon Sep 17 00:00:00 2001 From: Hirsch Alter Date: Mon, 3 Jan 2022 17:05:59 +0200 Subject: [PATCH 4/5] Add typehint in test (#127) --- tests/test_filelock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_filelock.py b/tests/test_filelock.py index 99b2920..bce9e1e 100644 --- a/tests/test_filelock.py +++ b/tests/test_filelock.py @@ -376,7 +376,7 @@ def test_context_decorator(lock_type: type[BaseFileLock], tmp_path: Path) -> Non lock = lock_type(str(lock_path)) @lock - def decorated_method(): + def decorated_method() -> None: assert lock.is_locked assert not lock.is_locked From 3edb257348fd0c5c537d45e60055b09e00179d2d Mon Sep 17 00:00:00 2001 From: Hirsch Alter Date: Tue, 4 Jan 2022 09:01:13 +0200 Subject: [PATCH 5/5] index.rst lock decorator just print the message and avoid the file open --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 072aa01..73b4e36 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -70,7 +70,7 @@ locks: @lock def decorated(): - open(file_path, "a").write("You're a decorated Jedi!") + print("You're a decorated Jedi!") decorated()