checkpointer 2.14.9__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.9 → checkpointer-2.14.10}/PKG-INFO +1 -1
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/checkpoint.py +14 -17
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/object_hash.py +11 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/pyproject.toml +1 -1
- {checkpointer-2.14.9 → checkpointer-2.14.10}/uv.lock +1 -1
- {checkpointer-2.14.9 → checkpointer-2.14.10}/.gitignore +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/.python-version +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/ATTRIBUTION.md +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/LICENSE +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/README.md +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/__init__.py +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/fn_ident.py +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/fn_string.py +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/import_mappings.py +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/print_checkpoint.py +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/storages/__init__.py +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/storages/memory_storage.py +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/storages/pickle_storage.py +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/storages/storage.py +0 -0
- {checkpointer-2.14.9 → checkpointer-2.14.10}/checkpointer/types.py +0 -0
- {checkpointer-2.14.9 → 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]:
|
|
@@ -184,11 +184,11 @@ class CachedFunction(Generic[Fn]):
|
|
|
184
184
|
elif key == b"**":
|
|
185
185
|
for key in kw.keys() - ident.arg_names:
|
|
186
186
|
named_args[key] = hash_by(named_args[key])
|
|
187
|
-
|
|
187
|
+
return ObjectHash(digest_size=16) \
|
|
188
188
|
.update(header="NAMED", iter=flatten(sorted(named_args.items()))) \
|
|
189
189
|
.update(header="POS", iter=pos_args) \
|
|
190
|
-
.update(header="CAPTURED", iter=flatten(c.capture() for c in ident.capturables))
|
|
191
|
-
|
|
190
|
+
.update(header="CAPTURED", iter=flatten(c.capture() for c in ident.capturables)) \
|
|
191
|
+
.hexdigest()
|
|
192
192
|
|
|
193
193
|
def get_call_hash(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> str:
|
|
194
194
|
return self._get_call_hash(args, kw)
|
|
@@ -203,15 +203,13 @@ class CachedFunction(Generic[Fn]):
|
|
|
203
203
|
def is_expired(self, call_hash: str) -> bool:
|
|
204
204
|
return not self.storage.exists(call_hash) or self.storage.expired(call_hash)
|
|
205
205
|
|
|
206
|
-
def _call(self: CachedFunction[Callable[P, R]], args: tuple, kw: dict,
|
|
207
|
-
params = self.ident.checkpointer
|
|
208
|
-
if not cached:
|
|
209
|
-
return self.fn(*args, **kw)
|
|
206
|
+
def _call(self: CachedFunction[Callable[P, R]], args: tuple, kw: dict, rerun=False) -> R:
|
|
210
207
|
call_hash = self._get_call_hash(args, kw)
|
|
211
208
|
call_id = f"{self.storage.fn_id()}/{call_hash}"
|
|
209
|
+
verbosity = self.ident.checkpointer.verbosity
|
|
212
210
|
|
|
213
211
|
if rerun or self.is_expired(call_hash):
|
|
214
|
-
print_checkpoint(
|
|
212
|
+
print_checkpoint(verbosity >= 1, "MEMORIZING", call_id, "blue")
|
|
215
213
|
data = self.fn(*args, **kw)
|
|
216
214
|
if iscoroutine(data):
|
|
217
215
|
return self._store_coroutine(call_hash, data)
|
|
@@ -219,23 +217,22 @@ class CachedFunction(Generic[Fn]):
|
|
|
219
217
|
|
|
220
218
|
try:
|
|
221
219
|
data = self.storage.load(call_hash)
|
|
222
|
-
print_checkpoint(
|
|
220
|
+
print_checkpoint(verbosity >= 2, "REMEMBERED", call_id, "green")
|
|
223
221
|
if isinstance(data, AwaitableValue):
|
|
224
222
|
return to_coroutine(data.value) # type: ignore
|
|
225
223
|
return data
|
|
226
224
|
except (EOFError, FileNotFoundError):
|
|
227
225
|
pass
|
|
228
|
-
print_checkpoint(
|
|
226
|
+
print_checkpoint(verbosity >= 1, "CORRUPTED", call_id, "yellow")
|
|
229
227
|
return self._call(args, kw, rerun=True)
|
|
230
228
|
|
|
231
229
|
def __call__(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> R:
|
|
232
|
-
|
|
230
|
+
if not self.ident.checkpointer.when:
|
|
231
|
+
return self.fn(*args, **kw)
|
|
232
|
+
return self._call(args, kw)
|
|
233
233
|
|
|
234
234
|
def cached(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> R:
|
|
235
|
-
return self._call(args, kw
|
|
236
|
-
|
|
237
|
-
def uncached(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> R:
|
|
238
|
-
return self._call(args, kw, False)
|
|
235
|
+
return self._call(args, kw)
|
|
239
236
|
|
|
240
237
|
def rerun(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> R:
|
|
241
238
|
return self._call(args, kw, rerun=True)
|
|
@@ -68,6 +68,17 @@ class ObjectHash:
|
|
|
68
68
|
def __eq__(self, value: object) -> bool:
|
|
69
69
|
return isinstance(value, ObjectHash) and str(self) == str(value)
|
|
70
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
|
+
|
|
71
82
|
def nested_hash(self, *objs: object) -> str:
|
|
72
83
|
return ObjectHash(iter=objs, tolerable=self.tolerable.value).hexdigest()
|
|
73
84
|
|
|
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
|