checkpointer 2.14.8__tar.gz → 2.14.10__tar.gz
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-2.14.8 → checkpointer-2.14.10}/PKG-INFO +1 -1
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/checkpoint.py +18 -17
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/object_hash.py +14 -1
- {checkpointer-2.14.8 → checkpointer-2.14.10}/pyproject.toml +1 -1
- {checkpointer-2.14.8 → checkpointer-2.14.10}/uv.lock +1 -1
- {checkpointer-2.14.8 → checkpointer-2.14.10}/.gitignore +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/.python-version +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/ATTRIBUTION.md +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/LICENSE +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/README.md +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/__init__.py +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/fn_ident.py +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/fn_string.py +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/import_mappings.py +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/print_checkpoint.py +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/storages/__init__.py +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/storages/memory_storage.py +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/storages/pickle_storage.py +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/storages/storage.py +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/types.py +0 -0
- {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: checkpointer
|
|
3
|
-
Version: 2.14.
|
|
3
|
+
Version: 2.14.10
|
|
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
|
|
@@ -96,10 +96,10 @@ class FunctionIdent:
|
|
|
96
96
|
@cached_property
|
|
97
97
|
def fn_hash(self) -> str:
|
|
98
98
|
if self.is_static():
|
|
99
|
-
return
|
|
99
|
+
return ObjectHash(self.checkpointer.fn_hash_from, digest_size=16).hexdigest()
|
|
100
100
|
depends = self.deep_idents(past_static=False)
|
|
101
101
|
deep_hashes = [d.fn_hash if d.is_static() else d.raw_ident.fn_hash for d in depends]
|
|
102
|
-
return
|
|
102
|
+
return ObjectHash(digest_size=16).write_text(iter=deep_hashes).hexdigest()
|
|
103
103
|
|
|
104
104
|
@cached_property
|
|
105
105
|
def capturables(self) -> list[Capturable]:
|
|
@@ -150,6 +150,8 @@ class CachedFunction(Generic[Fn]):
|
|
|
150
150
|
|
|
151
151
|
@property
|
|
152
152
|
def fn(self) -> Fn:
|
|
153
|
+
if self.bound:
|
|
154
|
+
return self.ident.fn.__get__(self.bound[0], self.bound[0].__class__) # type: ignore
|
|
153
155
|
return self.ident.fn # type: ignore
|
|
154
156
|
|
|
155
157
|
@cached_property
|
|
@@ -182,11 +184,11 @@ class CachedFunction(Generic[Fn]):
|
|
|
182
184
|
elif key == b"**":
|
|
183
185
|
for key in kw.keys() - ident.arg_names:
|
|
184
186
|
named_args[key] = hash_by(named_args[key])
|
|
185
|
-
|
|
187
|
+
return ObjectHash(digest_size=16) \
|
|
186
188
|
.update(header="NAMED", iter=flatten(sorted(named_args.items()))) \
|
|
187
189
|
.update(header="POS", iter=pos_args) \
|
|
188
|
-
.update(header="CAPTURED", iter=flatten(c.capture() for c in ident.capturables))
|
|
189
|
-
|
|
190
|
+
.update(header="CAPTURED", iter=flatten(c.capture() for c in ident.capturables)) \
|
|
191
|
+
.hexdigest()
|
|
190
192
|
|
|
191
193
|
def get_call_hash(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> str:
|
|
192
194
|
return self._get_call_hash(args, kw)
|
|
@@ -201,40 +203,39 @@ class CachedFunction(Generic[Fn]):
|
|
|
201
203
|
def is_expired(self, call_hash: str) -> bool:
|
|
202
204
|
return not self.storage.exists(call_hash) or self.storage.expired(call_hash)
|
|
203
205
|
|
|
204
|
-
def _call(self: CachedFunction[Callable[P, R]], args: tuple, kw: dict, rerun=False
|
|
205
|
-
full_args = self.bound + args
|
|
206
|
-
params = self.ident.checkpointer
|
|
207
|
-
if not params.when and not cached:
|
|
208
|
-
return self.fn(*full_args, **kw)
|
|
206
|
+
def _call(self: CachedFunction[Callable[P, R]], args: tuple, kw: dict, rerun=False) -> R:
|
|
209
207
|
call_hash = self._get_call_hash(args, kw)
|
|
210
208
|
call_id = f"{self.storage.fn_id()}/{call_hash}"
|
|
209
|
+
verbosity = self.ident.checkpointer.verbosity
|
|
211
210
|
|
|
212
211
|
if rerun or self.is_expired(call_hash):
|
|
213
|
-
print_checkpoint(
|
|
214
|
-
data = self.fn(*
|
|
212
|
+
print_checkpoint(verbosity >= 1, "MEMORIZING", call_id, "blue")
|
|
213
|
+
data = self.fn(*args, **kw)
|
|
215
214
|
if iscoroutine(data):
|
|
216
215
|
return self._store_coroutine(call_hash, data)
|
|
217
216
|
return self.storage.store(call_hash, data)
|
|
218
217
|
|
|
219
218
|
try:
|
|
220
219
|
data = self.storage.load(call_hash)
|
|
221
|
-
print_checkpoint(
|
|
220
|
+
print_checkpoint(verbosity >= 2, "REMEMBERED", call_id, "green")
|
|
222
221
|
if isinstance(data, AwaitableValue):
|
|
223
222
|
return to_coroutine(data.value) # type: ignore
|
|
224
223
|
return data
|
|
225
224
|
except (EOFError, FileNotFoundError):
|
|
226
225
|
pass
|
|
227
|
-
print_checkpoint(
|
|
228
|
-
return self._call(args, kw, True
|
|
226
|
+
print_checkpoint(verbosity >= 1, "CORRUPTED", call_id, "yellow")
|
|
227
|
+
return self._call(args, kw, rerun=True)
|
|
229
228
|
|
|
230
229
|
def __call__(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> R:
|
|
230
|
+
if not self.ident.checkpointer.when:
|
|
231
|
+
return self.fn(*args, **kw)
|
|
231
232
|
return self._call(args, kw)
|
|
232
233
|
|
|
233
234
|
def cached(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> R:
|
|
234
|
-
return self._call(args, kw
|
|
235
|
+
return self._call(args, kw)
|
|
235
236
|
|
|
236
237
|
def rerun(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> R:
|
|
237
|
-
return self._call(args, kw, True
|
|
238
|
+
return self._call(args, kw, rerun=True)
|
|
238
239
|
|
|
239
240
|
def exists(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> bool:
|
|
240
241
|
return self.storage.exists(self._get_call_hash(args, kw))
|
|
@@ -35,6 +35,8 @@ else:
|
|
|
35
35
|
nc = nullcontext()
|
|
36
36
|
stdlib = Path(sysconfig.get_paths()["stdlib"]).resolve()
|
|
37
37
|
|
|
38
|
+
Buffer = bytes | bytearray | memoryview
|
|
39
|
+
|
|
38
40
|
def encode_type(t: type | FunctionType) -> str:
|
|
39
41
|
return f"{t.__module__}:{t.__qualname__}"
|
|
40
42
|
|
|
@@ -66,10 +68,21 @@ class ObjectHash:
|
|
|
66
68
|
def __eq__(self, value: object) -> bool:
|
|
67
69
|
return isinstance(value, ObjectHash) and str(self) == str(value)
|
|
68
70
|
|
|
71
|
+
def __hash__(self) -> int:
|
|
72
|
+
self.update = self.write_bytes = self.write_text = self._update_immutable
|
|
73
|
+
return hash(str(self))
|
|
74
|
+
|
|
75
|
+
def _update_immutable(self, *_, **__) -> Self:
|
|
76
|
+
raise TypeError(
|
|
77
|
+
"This ObjectHash instance is now immutable and can’t accept more data. "
|
|
78
|
+
"You already called __hash__, which freezes it. "
|
|
79
|
+
"Create a new ObjectHash or use .copy() if you need to continue hashing."
|
|
80
|
+
)
|
|
81
|
+
|
|
69
82
|
def nested_hash(self, *objs: object) -> str:
|
|
70
83
|
return ObjectHash(iter=objs, tolerable=self.tolerable.value).hexdigest()
|
|
71
84
|
|
|
72
|
-
def write_bytes(self, *data:
|
|
85
|
+
def write_bytes(self, *data: Buffer, iter: Iterable[Buffer] = ()) -> Self:
|
|
73
86
|
for d in chain(data, iter):
|
|
74
87
|
self.hash.update(d)
|
|
75
88
|
return self
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|