checkpointer 2.14.4__py3-none-any.whl → 2.14.6__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/checkpoint.py +10 -4
- checkpointer/storages/memory_storage.py +16 -6
- checkpointer/storages/pickle_storage.py +6 -3
- checkpointer/storages/storage.py +4 -4
- checkpointer/utils.py +4 -4
- {checkpointer-2.14.4.dist-info → checkpointer-2.14.6.dist-info}/METADATA +1 -1
- {checkpointer-2.14.4.dist-info → checkpointer-2.14.6.dist-info}/RECORD +10 -10
- {checkpointer-2.14.4.dist-info → checkpointer-2.14.6.dist-info}/WHEEL +0 -0
- {checkpointer-2.14.4.dist-info → checkpointer-2.14.6.dist-info}/licenses/ATTRIBUTION.md +0 -0
- {checkpointer-2.14.4.dist-info → checkpointer-2.14.6.dist-info}/licenses/LICENSE +0 -0
checkpointer/checkpoint.py
CHANGED
@@ -25,7 +25,7 @@ class CheckpointerOpts(TypedDict, total=False):
|
|
25
25
|
directory: Path | str | None
|
26
26
|
when: bool
|
27
27
|
verbosity: Literal[0, 1, 2]
|
28
|
-
expiry: Callable[[datetime], bool] |
|
28
|
+
expiry: timedelta | Callable[[datetime], bool] | None
|
29
29
|
capture: bool
|
30
30
|
fn_hash_from: object
|
31
31
|
|
@@ -127,11 +127,8 @@ class FunctionIdent:
|
|
127
127
|
|
128
128
|
class CachedFunction(Generic[Fn]):
|
129
129
|
def __init__(self, checkpointer: Checkpointer, fn: Fn):
|
130
|
-
store_format = checkpointer.storage
|
131
|
-
Storage = STORAGE_MAP[store_format] if isinstance(store_format, str) else store_format
|
132
130
|
update_wrapper(self, unwrap(fn)) # type: ignore
|
133
131
|
self.ident = FunctionIdent(self, checkpointer, fn)
|
134
|
-
self.storage = Storage(self)
|
135
132
|
self.bound = ()
|
136
133
|
|
137
134
|
@overload
|
@@ -154,6 +151,12 @@ class CachedFunction(Generic[Fn]):
|
|
154
151
|
def fn(self) -> Fn:
|
155
152
|
return self.ident.fn # type: ignore
|
156
153
|
|
154
|
+
@cached_property
|
155
|
+
def storage(self) -> Storage:
|
156
|
+
store_format = self.ident.checkpointer.storage
|
157
|
+
Storage = STORAGE_MAP[store_format] if isinstance(store_format, str) else store_format
|
158
|
+
return Storage(self)
|
159
|
+
|
157
160
|
@property
|
158
161
|
def cleanup(self):
|
159
162
|
return self.storage.cleanup
|
@@ -260,6 +263,9 @@ class CachedFunction(Generic[Fn]):
|
|
260
263
|
def set(self, value, *args, **kw):
|
261
264
|
self.storage.store(self._get_call_hash(args, kw), value)
|
262
265
|
|
266
|
+
def set_awaitable(self: CachedFunction[Callable[P, Coro[R]]], value: R, *args: P.args, **kw: P.kwargs):
|
267
|
+
self.set(AwaitableValue(value), *args, **kw)
|
268
|
+
|
263
269
|
def __repr__(self) -> str:
|
264
270
|
initialized = "fn_hash" in self.ident.__dict__
|
265
271
|
fn_hash = self.ident.fn_hash[:6] if initialized else "- uninitialized"
|
@@ -1,12 +1,23 @@
|
|
1
|
+
from __future__ import annotations
|
1
2
|
import gc
|
2
|
-
from typing import Any
|
3
|
-
from pathlib import Path
|
4
3
|
from datetime import datetime
|
4
|
+
from pathlib import Path
|
5
|
+
from typing import TYPE_CHECKING, Any
|
6
|
+
from weakref import WeakSet
|
5
7
|
from .storage import Storage
|
6
8
|
|
9
|
+
if TYPE_CHECKING:
|
10
|
+
from ..checkpoint import CachedFunction
|
11
|
+
|
7
12
|
item_map: dict[Path, dict[str, tuple[datetime, Any]]] = {}
|
13
|
+
mem_stores: WeakSet[MemoryStorage] = WeakSet()
|
8
14
|
|
9
15
|
class MemoryStorage(Storage):
|
16
|
+
def __init__(self, cached_fn: CachedFunction):
|
17
|
+
super().__init__(cached_fn)
|
18
|
+
self.cleanup()
|
19
|
+
mem_stores.add(self)
|
20
|
+
|
10
21
|
def get_dict(self):
|
11
22
|
return item_map.setdefault(self.fn_dir(), {})
|
12
23
|
|
@@ -45,9 +56,8 @@ class MemoryStorage(Storage):
|
|
45
56
|
|
46
57
|
def cleanup_memory_storage():
|
47
58
|
gc.collect()
|
48
|
-
|
49
|
-
storage_keys = {store.fn_dir() for store in memory_stores}
|
59
|
+
storage_keys = {store.fn_dir() for store in mem_stores}
|
50
60
|
for key in item_map.keys() - storage_keys:
|
51
61
|
del item_map[key]
|
52
|
-
for store in
|
53
|
-
store.cleanup(
|
62
|
+
for store in mem_stores:
|
63
|
+
store.cleanup()
|
@@ -53,15 +53,18 @@ class PickleStorage(Storage):
|
|
53
53
|
if invalidated and fn_path.exists():
|
54
54
|
old_dirs = [path for path in fn_path.iterdir() if path.is_dir() and path != version_path]
|
55
55
|
for path in old_dirs:
|
56
|
-
|
57
|
-
|
56
|
+
for pkl_path in path.glob("**/*.pkl"):
|
57
|
+
pkl_path.unlink(missing_ok=True)
|
58
|
+
if old_dirs:
|
59
|
+
print(f"Removed {len(old_dirs)} invalidated directories for {self.cached_fn.__qualname__}")
|
58
60
|
if expired and self.checkpointer.expiry:
|
59
61
|
count = 0
|
60
62
|
for pkl_path in fn_path.glob("**/*.pkl"):
|
61
63
|
if self.expired_dt(filedate(pkl_path)):
|
62
64
|
count += 1
|
63
65
|
pkl_path.unlink(missing_ok=True)
|
64
|
-
|
66
|
+
if count:
|
67
|
+
print(f"Removed {count} expired checkpoints for {self.cached_fn.__qualname__}")
|
65
68
|
clear_directory(fn_path)
|
66
69
|
|
67
70
|
def clear(self):
|
checkpointer/storages/storage.py
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
-
from typing import Any, TYPE_CHECKING
|
3
|
-
from pathlib import Path
|
4
2
|
from datetime import datetime, timedelta
|
3
|
+
from pathlib import Path
|
4
|
+
from typing import TYPE_CHECKING, Any
|
5
5
|
|
6
6
|
if TYPE_CHECKING:
|
7
|
-
from ..checkpoint import
|
7
|
+
from ..checkpoint import CachedFunction, Checkpointer
|
8
8
|
|
9
9
|
class Storage:
|
10
10
|
checkpointer: Checkpointer
|
@@ -22,7 +22,7 @@ class Storage:
|
|
22
22
|
return self.checkpointer.directory / self.fn_id()
|
23
23
|
|
24
24
|
def expired(self, call_hash: str) -> bool:
|
25
|
-
if
|
25
|
+
if self.checkpointer.expiry is None:
|
26
26
|
return False
|
27
27
|
return self.expired_dt(self.checkpoint_date(call_hash))
|
28
28
|
|
checkpointer/utils.py
CHANGED
@@ -121,15 +121,15 @@ def empty_dirs(path: Path) -> Iterable[Path]:
|
|
121
121
|
for child in path.iterdir():
|
122
122
|
nonempty_count += 1
|
123
123
|
if child.is_dir():
|
124
|
-
for
|
125
|
-
yield
|
126
|
-
nonempty_count -= child ==
|
124
|
+
for descendant in empty_dirs(child):
|
125
|
+
yield descendant
|
126
|
+
nonempty_count -= child == descendant
|
127
127
|
if nonempty_count == 0:
|
128
128
|
yield path
|
129
129
|
|
130
130
|
def clear_directory(path: Path):
|
131
131
|
if path.is_dir():
|
132
132
|
for file in path.glob("**/.DS_Store"):
|
133
|
-
file.unlink()
|
133
|
+
file.unlink(missing_ok=True)
|
134
134
|
for directory in empty_dirs(path):
|
135
135
|
directory.rmdir()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: checkpointer
|
3
|
-
Version: 2.14.
|
3
|
+
Version: 2.14.6
|
4
4
|
Summary: checkpointer adds code-aware caching to Python functions, maintaining correctness and speeding up execution as your code changes.
|
5
5
|
Project-URL: Repository, https://github.com/Reddan/checkpointer.git
|
6
6
|
Author: Hampus Hallman
|
@@ -1,18 +1,18 @@
|
|
1
1
|
checkpointer/__init__.py,sha256=lprhgo4BcVbr4RczWdkNIWroVX_9M-akZcMbxOAWHf0,981
|
2
|
-
checkpointer/checkpoint.py,sha256=
|
2
|
+
checkpointer/checkpoint.py,sha256=BG2LkBbnCxWAzSTCNdYFJElef7LIFu29MvZqRp0RFrc,10665
|
3
3
|
checkpointer/fn_ident.py,sha256=Z2HtkoG8n0ddqNzjejnKW6Lo-ID2unKQZa1tOpRGujs,6911
|
4
4
|
checkpointer/fn_string.py,sha256=YldjAU91cwiZNwuE_AQN_DMiQCPAhGiiC3lPi0uvM0g,2579
|
5
5
|
checkpointer/import_mappings.py,sha256=ESqWvZTzYAmaVnJ6NulUvn3_8CInOOPmEKUXO2WD_WA,1794
|
6
6
|
checkpointer/object_hash.py,sha256=_VgyTEoe3H6268KBAOFZxSgWHb6otgG-3NzhHyehxe4,8595
|
7
7
|
checkpointer/print_checkpoint.py,sha256=uUQ493fJCaB4nhp4Ox60govSCiBTIPbBX15zt2QiRGo,1356
|
8
8
|
checkpointer/types.py,sha256=GFqbGACdDxzQX3bb2LmF9UxQVWOEisGvdtobnqCBAOA,1129
|
9
|
-
checkpointer/utils.py,sha256=
|
9
|
+
checkpointer/utils.py,sha256=WGfVeHeZua010YXMuDPwAYfyQyB6k2bm0n0nbZdJ28Q,3565
|
10
10
|
checkpointer/storages/__init__.py,sha256=p-r4YrPXn505_S3qLrSXHSlsEtb13w_DFnCt9IiUomk,296
|
11
|
-
checkpointer/storages/memory_storage.py,sha256=
|
12
|
-
checkpointer/storages/pickle_storage.py,sha256=
|
13
|
-
checkpointer/storages/storage.py,sha256=
|
14
|
-
checkpointer-2.14.
|
15
|
-
checkpointer-2.14.
|
16
|
-
checkpointer-2.14.
|
17
|
-
checkpointer-2.14.
|
18
|
-
checkpointer-2.14.
|
11
|
+
checkpointer/storages/memory_storage.py,sha256=M5O3gRMHBiG3CgMcFdA6-iDGvfafKqTi9nN3u8sETCg,1801
|
12
|
+
checkpointer/storages/pickle_storage.py,sha256=L6E7cugbn-XGMMlcHCFBJ-rBLbmtzbiPwRrlgfRd7yc,2304
|
13
|
+
checkpointer/storages/storage.py,sha256=5v_9Mp8__oqPnyrGsUEiT7jU4eMk9L4ORHDZeQw-TU4,1370
|
14
|
+
checkpointer-2.14.6.dist-info/METADATA,sha256=q-QYZcNIAkQ-3AcnIuKaXtifxwlIqYPU3vy86gTFGBQ,11215
|
15
|
+
checkpointer-2.14.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
16
|
+
checkpointer-2.14.6.dist-info/licenses/ATTRIBUTION.md,sha256=WF6L7-sD4s9t9ytVJOhjhpDoZ6TrWpqE3_bMdDIeJxI,1078
|
17
|
+
checkpointer-2.14.6.dist-info/licenses/LICENSE,sha256=drXs6vIb7uW49r70UuMz2A1VtOCl626kiTbcmrar1Xo,1072
|
18
|
+
checkpointer-2.14.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|