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.
Files changed (21) hide show
  1. {checkpointer-2.14.8 → checkpointer-2.14.10}/PKG-INFO +1 -1
  2. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/checkpoint.py +18 -17
  3. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/object_hash.py +14 -1
  4. {checkpointer-2.14.8 → checkpointer-2.14.10}/pyproject.toml +1 -1
  5. {checkpointer-2.14.8 → checkpointer-2.14.10}/uv.lock +1 -1
  6. {checkpointer-2.14.8 → checkpointer-2.14.10}/.gitignore +0 -0
  7. {checkpointer-2.14.8 → checkpointer-2.14.10}/.python-version +0 -0
  8. {checkpointer-2.14.8 → checkpointer-2.14.10}/ATTRIBUTION.md +0 -0
  9. {checkpointer-2.14.8 → checkpointer-2.14.10}/LICENSE +0 -0
  10. {checkpointer-2.14.8 → checkpointer-2.14.10}/README.md +0 -0
  11. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/__init__.py +0 -0
  12. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/fn_ident.py +0 -0
  13. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/fn_string.py +0 -0
  14. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/import_mappings.py +0 -0
  15. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/print_checkpoint.py +0 -0
  16. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/storages/__init__.py +0 -0
  17. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/storages/memory_storage.py +0 -0
  18. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/storages/pickle_storage.py +0 -0
  19. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/storages/storage.py +0 -0
  20. {checkpointer-2.14.8 → checkpointer-2.14.10}/checkpointer/types.py +0 -0
  21. {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.8
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 str(ObjectHash(self.checkpointer.fn_hash_from, digest_size=16))
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 str(ObjectHash(digest_size=16).write_text(iter=deep_hashes))
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
- call_hash = ObjectHash(digest_size=16) \
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
- return str(call_hash)
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, cached=False) -> R:
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(params.verbosity >= 1, "MEMORIZING", call_id, "blue")
214
- data = self.fn(*full_args, **kw)
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(params.verbosity >= 2, "REMEMBERED", call_id, "green")
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(params.verbosity >= 1, "CORRUPTED", call_id, "yellow")
228
- return self._call(args, kw, True, cached)
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, False, True)
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, 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: bytes, iter: Iterable[bytes] = ()) -> Self:
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "checkpointer"
3
- version = "2.14.8"
3
+ version = "2.14.10"
4
4
  requires-python = ">=3.11"
5
5
  dependencies = []
6
6
  authors = [
@@ -8,7 +8,7 @@ resolution-markers = [
8
8
 
9
9
  [[package]]
10
10
  name = "checkpointer"
11
- version = "2.14.8"
11
+ version = "2.14.10"
12
12
  source = { editable = "." }
13
13
 
14
14
  [package.dev-dependencies]
File without changes
File without changes
File without changes