checkpointer 2.7.0__py3-none-any.whl → 2.7.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checkpointer/__init__.py +2 -1
- checkpointer/checkpoint.py +8 -5
- checkpointer/object_hash.py +3 -0
- checkpointer/test_checkpointer.py +14 -14
- {checkpointer-2.7.0.dist-info → checkpointer-2.7.1.dist-info}/METADATA +1 -1
- {checkpointer-2.7.0.dist-info → checkpointer-2.7.1.dist-info}/RECORD +8 -8
- {checkpointer-2.7.0.dist-info → checkpointer-2.7.1.dist-info}/WHEEL +0 -0
- {checkpointer-2.7.0.dist-info → checkpointer-2.7.1.dist-info}/licenses/LICENSE +0 -0
checkpointer/__init__.py
CHANGED
@@ -9,7 +9,8 @@ create_checkpointer = Checkpointer
|
|
9
9
|
checkpoint = Checkpointer()
|
10
10
|
capture_checkpoint = Checkpointer(capture=True)
|
11
11
|
memory_checkpoint = Checkpointer(format="memory", verbosity=0)
|
12
|
-
tmp_checkpoint = Checkpointer(root_path=tempfile.gettempdir()
|
12
|
+
tmp_checkpoint = Checkpointer(root_path=f"{tempfile.gettempdir()}/checkpoints")
|
13
|
+
static_checkpoint = Checkpointer(fn_hash=ObjectHash())
|
13
14
|
|
14
15
|
def cleanup_all(invalidated=True, expired=True):
|
15
16
|
for obj in gc.get_objects():
|
checkpointer/checkpoint.py
CHANGED
@@ -4,7 +4,7 @@ import re
|
|
4
4
|
from datetime import datetime
|
5
5
|
from functools import update_wrapper
|
6
6
|
from pathlib import Path
|
7
|
-
from typing import Any, Callable, Generic, Iterable, Literal, Type, TypedDict, TypeVar, Unpack, cast, overload
|
7
|
+
from typing import Any, Callable, Generic, Iterable, Literal, ParamSpec, Type, TypedDict, TypeVar, Unpack, cast, overload
|
8
8
|
from .fn_ident import get_fn_ident
|
9
9
|
from .object_hash import ObjectHash
|
10
10
|
from .print_checkpoint import print_checkpoint
|
@@ -12,6 +12,8 @@ from .storages import STORAGE_MAP, Storage
|
|
12
12
|
from .utils import resolved_awaitable, sync_resolve_coroutine, unwrap_fn
|
13
13
|
|
14
14
|
Fn = TypeVar("Fn", bound=Callable)
|
15
|
+
P = ParamSpec("P")
|
16
|
+
R = TypeVar("R")
|
15
17
|
|
16
18
|
DEFAULT_DIR = Path.home() / ".cache/checkpoints"
|
17
19
|
|
@@ -127,20 +129,21 @@ class CheckpointFn(Generic[Fn]):
|
|
127
129
|
coroutine = self._store_on_demand(args, kw, rerun)
|
128
130
|
return coroutine if self.is_async else sync_resolve_coroutine(coroutine)
|
129
131
|
|
130
|
-
def
|
132
|
+
def get(self: Callable[P, R], *args: P.args, **kw: P.kwargs) -> R: # type: ignore
|
133
|
+
self = cast(CheckpointFn, self)
|
131
134
|
checkpoint_path = self.checkpointer.root_path / self.get_checkpoint_id(args, kw)
|
132
135
|
try:
|
133
136
|
val = self.storage.load(checkpoint_path)
|
134
|
-
return resolved_awaitable(val) if self.is_async else val
|
137
|
+
return cast(R, resolved_awaitable(val) if self.is_async else val)
|
135
138
|
except Exception as ex:
|
136
139
|
raise CheckpointError("Could not load checkpoint") from ex
|
137
140
|
|
138
|
-
def exists(self, *args:
|
141
|
+
def exists(self: Callable[P, R], *args: P.args, **kw: P.kwargs) -> bool: # type: ignore
|
142
|
+
self = cast(CheckpointFn, self)
|
139
143
|
return self.storage.exists(self.checkpointer.root_path / self.get_checkpoint_id(args, kw))
|
140
144
|
|
141
145
|
__call__: Fn = cast(Fn, lambda self, *args, **kw: self._call(args, kw))
|
142
146
|
rerun: Fn = cast(Fn, lambda self, *args, **kw: self._call(args, kw, True))
|
143
|
-
get: Fn = cast(Fn, lambda self, *args, **kw: self._get(args, kw))
|
144
147
|
|
145
148
|
def __repr__(self) -> str:
|
146
149
|
return f"<CheckpointFn {self.fn.__name__} {self.fn_hash[:6]}>"
|
checkpointer/object_hash.py
CHANGED
@@ -56,6 +56,9 @@ class ObjectHash:
|
|
56
56
|
|
57
57
|
__str__ = hexdigest
|
58
58
|
|
59
|
+
def __eq__(self, value: object) -> bool:
|
60
|
+
return isinstance(value, ObjectHash) and str(self) == str(value)
|
61
|
+
|
59
62
|
def nested_hash(self, *objs: Any) -> str:
|
60
63
|
return ObjectHash(iter=objs, tolerate_errors=self.tolerate_errors.value).hexdigest()
|
61
64
|
|
@@ -6,7 +6,7 @@ from . import checkpoint
|
|
6
6
|
from .checkpoint import CheckpointError
|
7
7
|
from .utils import AttrDict
|
8
8
|
|
9
|
-
def global_multiply(a, b):
|
9
|
+
def global_multiply(a: int, b: int) -> int:
|
10
10
|
return a * b
|
11
11
|
|
12
12
|
@pytest.fixture(autouse=True)
|
@@ -27,15 +27,15 @@ def test_basic_caching():
|
|
27
27
|
|
28
28
|
def test_cache_invalidation():
|
29
29
|
@checkpoint
|
30
|
-
def multiply(a, b):
|
30
|
+
def multiply(a: int, b: int):
|
31
31
|
return a * b
|
32
32
|
|
33
33
|
@checkpoint
|
34
|
-
def helper(x):
|
34
|
+
def helper(x: int):
|
35
35
|
return multiply(x + 1, 2)
|
36
36
|
|
37
37
|
@checkpoint
|
38
|
-
def compute(a, b):
|
38
|
+
def compute(a: int, b: int):
|
39
39
|
return helper(a) + helper(b)
|
40
40
|
|
41
41
|
result1 = compute(3, 4)
|
@@ -46,7 +46,7 @@ def test_layered_caching():
|
|
46
46
|
|
47
47
|
@checkpoint(format="memory")
|
48
48
|
@dev_checkpoint
|
49
|
-
def expensive_function(x):
|
49
|
+
def expensive_function(x: int):
|
50
50
|
return x ** 2
|
51
51
|
|
52
52
|
assert expensive_function(4) == 16
|
@@ -95,7 +95,7 @@ def test_force_recalculation():
|
|
95
95
|
def test_multi_layer_decorator():
|
96
96
|
@checkpoint(format="memory")
|
97
97
|
@checkpoint(format="pickle")
|
98
|
-
def add(a, b):
|
98
|
+
def add(a: int, b: int) -> int:
|
99
99
|
return a + b
|
100
100
|
|
101
101
|
assert add(2, 3) == 5
|
@@ -124,18 +124,18 @@ def test_capture():
|
|
124
124
|
assert test_a.fn_hash != init_hash_a
|
125
125
|
|
126
126
|
def test_depends():
|
127
|
-
def multiply_wrapper(a, b):
|
127
|
+
def multiply_wrapper(a: int, b: int) -> int:
|
128
128
|
return global_multiply(a, b)
|
129
129
|
|
130
|
-
def helper(a, b):
|
130
|
+
def helper(a: int, b: int) -> int:
|
131
131
|
return multiply_wrapper(a + 1, b + 1)
|
132
132
|
|
133
133
|
@checkpoint
|
134
|
-
def test_a(a, b):
|
134
|
+
def test_a(a: int, b: int) -> int:
|
135
135
|
return helper(a, b)
|
136
136
|
|
137
137
|
@checkpoint
|
138
|
-
def test_b(a, b):
|
138
|
+
def test_b(a: int, b: int) -> int:
|
139
139
|
return test_a(a, b) + multiply_wrapper(a, b)
|
140
140
|
|
141
141
|
assert set(test_a.depends) == {test_a.fn, helper, multiply_wrapper, global_multiply}
|
@@ -143,17 +143,17 @@ def test_depends():
|
|
143
143
|
|
144
144
|
def test_lazy_init():
|
145
145
|
@checkpoint
|
146
|
-
def fn1(x):
|
146
|
+
def fn1(x: object) -> object:
|
147
147
|
return fn2(x)
|
148
148
|
|
149
149
|
@checkpoint
|
150
|
-
def fn2(x):
|
150
|
+
def fn2(x: object) -> object:
|
151
151
|
return fn1(x)
|
152
152
|
|
153
|
-
assert type(object.__getattribute__(fn1, "_getattribute"))
|
153
|
+
assert type(object.__getattribute__(fn1, "_getattribute")) is MethodType
|
154
154
|
with pytest.raises(AttributeError):
|
155
155
|
object.__getattribute__(fn1, "fn_hash")
|
156
156
|
assert fn1.fn_hash == object.__getattribute__(fn1, "fn_hash")
|
157
|
-
assert type(object.__getattribute__(fn1, "_getattribute"))
|
157
|
+
assert type(object.__getattribute__(fn1, "_getattribute")) is MethodWrapperType
|
158
158
|
assert set(fn1.depends) == {fn1.fn, fn2}
|
159
159
|
assert set(fn2.depends) == {fn1, fn2.fn}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: checkpointer
|
3
|
-
Version: 2.7.
|
3
|
+
Version: 2.7.1
|
4
4
|
Summary: A Python library for memoizing function results with support for multiple storage backends, async runtimes, and automatic cache invalidation
|
5
5
|
Project-URL: Repository, https://github.com/Reddan/checkpointer.git
|
6
6
|
Author: Hampus Hallman
|
@@ -1,16 +1,16 @@
|
|
1
|
-
checkpointer/__init__.py,sha256=
|
2
|
-
checkpointer/checkpoint.py,sha256=
|
1
|
+
checkpointer/__init__.py,sha256=HRLsQ24ZhxgmDcHchZ-hX6wA0NMCSedGA0NmCnUdS_c,832
|
2
|
+
checkpointer/checkpoint.py,sha256=H1RQJIIuEmRcXd42Y-qUfyU3z0OGp3smY0LoKQN0IYU,6425
|
3
3
|
checkpointer/fn_ident.py,sha256=SWaksNCTlskMom0ztqjECSRjZYPWXUA1p1ZCb-9tWo0,4297
|
4
|
-
checkpointer/object_hash.py,sha256=
|
4
|
+
checkpointer/object_hash.py,sha256=cxuWRDrg4F9wC18aC12zOZYOPv3bk2Qf6tZ0_WgAb6Y,7484
|
5
5
|
checkpointer/print_checkpoint.py,sha256=aJCeWMRJiIR3KpyPk_UOKTaD906kArGrmLGQ3LqcVgo,1369
|
6
|
-
checkpointer/test_checkpointer.py,sha256=
|
6
|
+
checkpointer/test_checkpointer.py,sha256=VdINXiaA_BoDdVYEB73ctfQ42fw3EDoYa9vYacoB13A,3768
|
7
7
|
checkpointer/utils.py,sha256=E1AV96NTh3tuVmgPrr0JSKZaokw-Jely5Y6-NjlMCp8,3141
|
8
8
|
checkpointer/storages/__init__.py,sha256=Kl4Og5jhYxn6m3tB_kTMsabf4_eWVLmFVAoC-pikNQE,301
|
9
9
|
checkpointer/storages/bcolz_storage.py,sha256=3QkSUSeG5s2kFuVV_LZpzMn1A5E7kqC7jk7w35c0NyQ,2314
|
10
10
|
checkpointer/storages/memory_storage.py,sha256=S5ayOZE_CyaFQJ-vSgObTanldPzG3gh3NksjNAc7vsk,1282
|
11
11
|
checkpointer/storages/pickle_storage.py,sha256=idh9sBMdWuyvS220oa_7bAUpc9Xo9v6Ud9aYKGWasUs,1593
|
12
12
|
checkpointer/storages/storage.py,sha256=_m18Z8TKrdAbi6YYYQmuNOnhna4RB2sJDn1v3liaU3U,721
|
13
|
-
checkpointer-2.7.
|
14
|
-
checkpointer-2.7.
|
15
|
-
checkpointer-2.7.
|
16
|
-
checkpointer-2.7.
|
13
|
+
checkpointer-2.7.1.dist-info/METADATA,sha256=wEdB7ZEnYVW3-bcwFBpZAQXbv76MNU1PvUpKMhW1Ids,10606
|
14
|
+
checkpointer-2.7.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
15
|
+
checkpointer-2.7.1.dist-info/licenses/LICENSE,sha256=9xVsdtv_-uSyY9Xl9yujwAPm4-mjcCLeVy-ljwXEWbo,1059
|
16
|
+
checkpointer-2.7.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|