Skip to content

Commit

Permalink
Properly pickle of Timeout objects + test cases (#203)
Browse files Browse the repository at this point in the history
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Bernát Gábor <bgabor8@bloomberg.net>
  • Loading branch information
3 people authored Mar 22, 2023
1 parent 66b2d49 commit 0b10287
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 6 deletions.
10 changes: 7 additions & 3 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
Changelog
=========
v3.10.1 (2023-03-22)
--------------------
- Handle pickle for :class:`filelock.Timeout` :pr:`203` - by :user:`TheMatt2`.

v3.10.0 (2023-03-15)
-------------------
- Add support for explicit file modes for lockfiles :pr:`192 - by :user:`jahrules`.
--------------------
- Add support for explicit file modes for lockfiles :pr:`192` - by :user:`jahrules`.

v3.9.1 (2023-03-14)
-------------------
- Use ``time.perf_counter`` instead of ``time.monotonic`` for calculating timeouts.

v3.9.0 (2022-12-28)
-------------------
- Move build backend to ``hatchling`` :pr:`185 - by :user:`gaborbernat`.
- Move build backend to ``hatchling`` :pr:`185` - by :user:`gaborbernat`.

v3.8.1 (2022-12-04)
-------------------
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ line-length = 120
[tool.isort]
profile = "black"
known_first_party = ["filelock"]
add_imports = ["from __future__ import annotations"]

[tool.mypy]
python_version = "3.11"
Expand Down
19 changes: 16 additions & 3 deletions src/filelock/_error.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
from __future__ import annotations

from typing import Any


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
super().__init__()
self._lock_file = lock_file

def __reduce__(self) -> str | tuple[Any, ...]:
return self.__class__, (self._lock_file,) # Properly pickle the exception

def __str__(self) -> str:
return f"The file lock '{self.lock_file}' could not be acquired."
return f"The file lock '{self._lock_file}' could not be acquired."

def __repr__(self) -> str:
return f"{self.__class__.__name__}({self.lock_file!r})"

@property
def lock_file(self) -> str:
""":return: The path of the file lock."""
return self._lock_file


__all__ = [
Expand Down
30 changes: 30 additions & 0 deletions tests/test_error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from __future__ import annotations

import pickle

from filelock import Timeout


def test_timeout_str() -> None:
timeout = Timeout("/path/to/lock")
assert str(timeout) == "The file lock '/path/to/lock' could not be acquired."


def test_timeout_repr() -> None:
timeout = Timeout("/path/to/lock")
assert repr(timeout) == "Timeout('/path/to/lock')"


def test_timeout_lock_file() -> None:
timeout = Timeout("/path/to/lock")
assert timeout.lock_file == "/path/to/lock"


def test_timeout_pickle() -> None:
timeout = Timeout("/path/to/lock")
timeout_loaded = pickle.loads(pickle.dumps(timeout))

assert timeout.__class__ == timeout_loaded.__class__
assert str(timeout) == str(timeout_loaded)
assert repr(timeout) == repr(timeout_loaded)
assert timeout.lock_file == timeout_loaded.lock_file

0 comments on commit 0b10287

Please sign in to comment.