checkpointer 2.11.0__py3-none-any.whl → 2.11.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.
@@ -129,7 +129,7 @@ class CachedFunction(Generic[Fn]):
129
129
  for ident in depend_idents: ident.fn_hash
130
130
  return self
131
131
 
132
- def get_call_id(self, args: tuple, kw: dict[str, object]) -> str:
132
+ def get_call_hash(self, args: tuple, kw: dict[str, object]) -> str:
133
133
  args = self.bound + args
134
134
  pos_args = args[len(self.arg_names):]
135
135
  named_pos_args = dict(zip(self.arg_names, args))
@@ -143,8 +143,8 @@ class CachedFunction(Generic[Fn]):
143
143
  pos_args = tuple(map(pos_hash_by, pos_args))
144
144
  return str(ObjectHash(named_args, pos_args, self.ident.captured_hash, digest_size=16))
145
145
 
146
- async def _resolve_coroutine(self, call_id: str, coroutine: Coroutine):
147
- return self.storage.store(call_id, AwaitableValue(await coroutine)).value
146
+ async def _resolve_coroutine(self, call_hash: str, coroutine: Coroutine):
147
+ return self.storage.store(call_hash, AwaitableValue(await coroutine)).value
148
148
 
149
149
  def _call(self: CachedFunction[Callable[P, R]], args: tuple, kw: dict, rerun=False) -> R:
150
150
  full_args = self.bound + args
@@ -152,27 +152,27 @@ class CachedFunction(Generic[Fn]):
152
152
  if not params.when:
153
153
  return self.fn(*full_args, **kw)
154
154
 
155
- call_id = self.get_call_id(args, kw)
156
- call_id_long = f"{self.fn_dir}/{self.ident.fn_hash}/{call_id}"
155
+ call_hash = self.get_call_hash(args, kw)
156
+ call_hash_long = f"{self.fn_dir}/{self.ident.fn_hash}/{call_hash}"
157
157
 
158
158
  refresh = rerun \
159
- or not self.storage.exists(call_id) \
160
- or (params.should_expire and params.should_expire(self.storage.checkpoint_date(call_id)))
159
+ or not self.storage.exists(call_hash) \
160
+ or (params.should_expire and params.should_expire(self.storage.checkpoint_date(call_hash)))
161
161
 
162
162
  if refresh:
163
- print_checkpoint(params.verbosity >= 1, "MEMORIZING", call_id_long, "blue")
163
+ print_checkpoint(params.verbosity >= 1, "MEMORIZING", call_hash_long, "blue")
164
164
  data = self.fn(*full_args, **kw)
165
165
  if iscoroutine(data):
166
- return self._resolve_coroutine(call_id, data)
167
- return self.storage.store(call_id, data)
166
+ return self._resolve_coroutine(call_hash, data)
167
+ return self.storage.store(call_hash, data)
168
168
 
169
169
  try:
170
- data = self.storage.load(call_id)
171
- print_checkpoint(params.verbosity >= 2, "REMEMBERED", call_id_long, "green")
170
+ data = self.storage.load(call_hash)
171
+ print_checkpoint(params.verbosity >= 2, "REMEMBERED", call_hash_long, "green")
172
172
  return data
173
173
  except (EOFError, FileNotFoundError):
174
174
  pass
175
- print_checkpoint(params.verbosity >= 1, "CORRUPTED", call_id_long, "yellow")
175
+ print_checkpoint(params.verbosity >= 1, "CORRUPTED", call_hash_long, "yellow")
176
176
  return self._call(args, kw, True)
177
177
 
178
178
  def __call__(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> R:
@@ -181,23 +181,30 @@ class CachedFunction(Generic[Fn]):
181
181
  def rerun(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> R:
182
182
  return self._call(args, kw, True)
183
183
 
184
+ def exists(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> bool:
185
+ return self.storage.exists(self.get_call_hash(args, kw))
186
+
187
+ def delete(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs):
188
+ self.storage.delete(self.get_call_hash(args, kw))
189
+
184
190
  @overload
185
191
  def get(self: Callable[P, Coroutine[object, object, R]], *args: P.args, **kw: P.kwargs) -> R: ...
186
192
  @overload
187
193
  def get(self: Callable[P, R], *args: P.args, **kw: P.kwargs) -> R: ...
188
194
  def get(self, *args, **kw):
189
- call_id = self.get_call_id(args, kw)
195
+ call_hash = self.get_call_hash(args, kw)
190
196
  try:
191
- data = self.storage.load(call_id)
197
+ data = self.storage.load(call_hash)
192
198
  return data.value if isinstance(data, AwaitableValue) else data
193
199
  except Exception as ex:
194
200
  raise CheckpointError("Could not load checkpoint") from ex
195
201
 
196
- def exists(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs) -> bool:
197
- return self.storage.exists(self.get_call_id(args, kw))
198
-
199
- def delete(self: CachedFunction[Callable[P, R]], *args: P.args, **kw: P.kwargs):
200
- self.storage.delete(self.get_call_id(args, kw))
202
+ @overload
203
+ def _set(self: Callable[P, Coroutine[object, object, R]], value: AwaitableValue[R], *args: P.args, **kw: P.kwargs): ...
204
+ @overload
205
+ def _set(self: Callable[P, R], value: R, *args: P.args, **kw: P.kwargs): ...
206
+ def _set(self, value, *args, **kw):
207
+ self.storage.store(self.get_call_hash(args, kw), value)
201
208
 
202
209
  def __repr__(self) -> str:
203
210
  return f"<CachedFunction {self.fn.__name__} {self.ident.fn_hash[:6]}>"
@@ -9,21 +9,21 @@ class MemoryStorage(Storage):
9
9
  def get_dict(self):
10
10
  return item_map.setdefault(self.fn_dir(), {})
11
11
 
12
- def store(self, call_id, data):
13
- self.get_dict()[call_id] = (datetime.now(), data)
12
+ def store(self, call_hash, data):
13
+ self.get_dict()[call_hash] = (datetime.now(), data)
14
14
  return data
15
15
 
16
- def exists(self, call_id):
17
- return call_id in self.get_dict()
16
+ def exists(self, call_hash):
17
+ return call_hash in self.get_dict()
18
18
 
19
- def checkpoint_date(self, call_id):
20
- return self.get_dict()[call_id][0]
19
+ def checkpoint_date(self, call_hash):
20
+ return self.get_dict()[call_hash][0]
21
21
 
22
- def load(self, call_id):
23
- return self.get_dict()[call_id][1]
22
+ def load(self, call_hash):
23
+ return self.get_dict()[call_hash][1]
24
24
 
25
- def delete(self, call_id):
26
- self.get_dict().pop(call_id, None)
25
+ def delete(self, call_hash):
26
+ self.get_dict().pop(call_hash, None)
27
27
 
28
28
  def cleanup(self, invalidated=True, expired=True):
29
29
  curr_key = self.fn_dir()
@@ -32,6 +32,6 @@ class MemoryStorage(Storage):
32
32
  if invalidated and key != curr_key:
33
33
  del item_map[key]
34
34
  elif expired and self.checkpointer.should_expire:
35
- for call_id, (date, _) in list(calldict.items()):
35
+ for call_hash, (date, _) in list(calldict.items()):
36
36
  if self.checkpointer.should_expire(date):
37
- del calldict[call_id]
37
+ del calldict[call_hash]
@@ -8,29 +8,29 @@ def filedate(path: Path) -> datetime:
8
8
  return datetime.fromtimestamp(path.stat().st_mtime)
9
9
 
10
10
  class PickleStorage(Storage):
11
- def get_path(self, call_id: str):
12
- return self.fn_dir() / f"{call_id}.pkl"
11
+ def get_path(self, call_hash: str):
12
+ return self.fn_dir() / f"{call_hash}.pkl"
13
13
 
14
- def store(self, call_id, data):
15
- path = self.get_path(call_id)
14
+ def store(self, call_hash, data):
15
+ path = self.get_path(call_hash)
16
16
  path.parent.mkdir(parents=True, exist_ok=True)
17
17
  with path.open("wb") as file:
18
18
  pickle.dump(data, file, -1)
19
19
  return data
20
20
 
21
- def exists(self, call_id):
22
- return self.get_path(call_id).exists()
21
+ def exists(self, call_hash):
22
+ return self.get_path(call_hash).exists()
23
23
 
24
- def checkpoint_date(self, call_id):
24
+ def checkpoint_date(self, call_hash):
25
25
  # Should use st_atime/access time?
26
- return filedate(self.get_path(call_id))
26
+ return filedate(self.get_path(call_hash))
27
27
 
28
- def load(self, call_id):
29
- with self.get_path(call_id).open("rb") as file:
28
+ def load(self, call_hash):
29
+ with self.get_path(call_hash).open("rb") as file:
30
30
  return pickle.load(file)
31
31
 
32
- def delete(self, call_id):
33
- self.get_path(call_id).unlink(missing_ok=True)
32
+ def delete(self, call_hash):
33
+ self.get_path(call_hash).unlink(missing_ok=True)
34
34
 
35
35
  def cleanup(self, invalidated=True, expired=True):
36
36
  version_path = self.fn_dir()
@@ -20,14 +20,14 @@ class Storage:
20
20
  def fn_dir(self) -> Path:
21
21
  return self.checkpointer.root_path / self.fn_id()
22
22
 
23
- def store(self, call_id: str, data: Any) -> Any: ...
23
+ def store(self, call_hash: str, data: Any) -> Any: ...
24
24
 
25
- def exists(self, call_id: str) -> bool: ...
25
+ def exists(self, call_hash: str) -> bool: ...
26
26
 
27
- def checkpoint_date(self, call_id: str) -> datetime: ...
27
+ def checkpoint_date(self, call_hash: str) -> datetime: ...
28
28
 
29
- def load(self, call_id: str) -> Any: ...
29
+ def load(self, call_hash: str) -> Any: ...
30
30
 
31
- def delete(self, call_id: str) -> None: ...
31
+ def delete(self, call_hash: str) -> None: ...
32
32
 
33
33
  def cleanup(self, invalidated=True, expired=True): ...
checkpointer/types.py CHANGED
@@ -8,8 +8,8 @@ class HashBy(Generic[Fn]):
8
8
 
9
9
  NoHash = Annotated[T, HashBy[lambda _: None]]
10
10
 
11
- class AwaitableValue:
12
- def __init__(self, value):
11
+ class AwaitableValue(Generic[T]):
12
+ def __init__(self, value: T):
13
13
  self.value = value
14
14
 
15
15
  def __await__(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: checkpointer
3
- Version: 2.11.0
3
+ Version: 2.11.1
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
@@ -166,7 +166,7 @@ In this example, the cache key for `numbers` ignores order, `data_file` is hashe
166
166
 
167
167
  For integration with databases, cloud storage, or custom serialization, implement your own storage backend by inheriting from `checkpointer.Storage` and implementing its abstract methods.
168
168
 
169
- Within custom storage methods, `call_id` identifies calls by arguments. Use `self.fn_id()` to get the function's unique identity (name + hash/version), crucial for organizing stored checkpoints (e.g., by function version). Access global `Checkpointer` config via `self.checkpointer`.
169
+ Within custom storage methods, `call_hash` identifies calls by arguments. Use `self.fn_id()` to get the function's unique identity (name + hash/version), crucial for organizing stored checkpoints (e.g., by function version). Access global `Checkpointer` config via `self.checkpointer`.
170
170
 
171
171
  **Example: Custom Storage Backend**
172
172
 
@@ -175,18 +175,18 @@ from checkpointer import checkpoint, Storage
175
175
  from datetime import datetime
176
176
 
177
177
  class MyCustomStorage(Storage):
178
- def exists(self, call_id):
178
+ def exists(self, call_hash):
179
179
  # Example: Constructing a path based on function ID and call ID
180
180
  fn_dir = self.checkpointer.root_path / self.fn_id()
181
- return (fn_dir / call_id).exists()
181
+ return (fn_dir / call_hash).exists()
182
182
 
183
- def store(self, call_id, data):
184
- ... # Store the serialized data for `call_id`
183
+ def store(self, call_hash, data):
184
+ ... # Store the serialized data for `call_hash`
185
185
  return data # This method must return the data back to checkpointer
186
186
 
187
- def checkpoint_date(self, call_id): ...
188
- def load(self, call_id): ...
189
- def delete(self, call_id): ...
187
+ def checkpoint_date(self, call_hash): ...
188
+ def load(self, call_hash): ...
189
+ def delete(self, call_hash): ...
190
190
 
191
191
  @checkpoint(format=MyCustomStorage)
192
192
  def custom_cached_function(x: int):
@@ -0,0 +1,16 @@
1
+ checkpointer/__init__.py,sha256=ayjFyHwvl_HRHwocY-hOJvAx0Ko5X9IMZrNT4CwfoMU,824
2
+ checkpointer/checkpoint.py,sha256=fSIgZATbTMBwZWLeWH3wIzHoPRQ5LySeb9Ygi30rCg8,9415
3
+ checkpointer/fn_ident.py,sha256=-5XbovQowVyYCFc7JdT9z1NoIEiL8h9fi7alF_34Ils,4470
4
+ checkpointer/object_hash.py,sha256=YlyFupQrg3V2mpzTLfOqpqlZWhoSCHliScQ4cKd36T0,8133
5
+ checkpointer/print_checkpoint.py,sha256=aJCeWMRJiIR3KpyPk_UOKTaD906kArGrmLGQ3LqcVgo,1369
6
+ checkpointer/test_checkpointer.py,sha256=-EvsMMNOOiIxhTcG97LLX0jUMWp534ko7qCKDSFWiA0,3802
7
+ checkpointer/types.py,sha256=_dxYqzqzV8GB_g-MQlN_Voie32syKy8u7RHbc0i4upY,338
8
+ checkpointer/utils.py,sha256=0cGVSlTnABgs3jI1uHoTfz353kkGa-qtTfe7jG4NCr0,2192
9
+ checkpointer/storages/__init__.py,sha256=en32nTUltpCSgz8RVGS_leIHC1Y1G89IqG1ZqAb6qUo,236
10
+ checkpointer/storages/memory_storage.py,sha256=aQRSOmAfS0UudubCpv8cdfu2ycM8mlsO9tFMcD2kmgo,1133
11
+ checkpointer/storages/pickle_storage.py,sha256=je1LM2lTSs5yzm25Apg5tJ9jU9T6nXCgD9SlqQRIFaM,1652
12
+ checkpointer/storages/storage.py,sha256=5Jel7VlmCG9gnIbZFKT1NrEiAePz8ZD8hfsD-tYEiP4,905
13
+ checkpointer-2.11.1.dist-info/METADATA,sha256=vpXrjRj8-yid19Lh_tU45cNdVkYalFj_RP3pRCm3S8A,11633
14
+ checkpointer-2.11.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
15
+ checkpointer-2.11.1.dist-info/licenses/LICENSE,sha256=9xVsdtv_-uSyY9Xl9yujwAPm4-mjcCLeVy-ljwXEWbo,1059
16
+ checkpointer-2.11.1.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- checkpointer/__init__.py,sha256=ayjFyHwvl_HRHwocY-hOJvAx0Ko5X9IMZrNT4CwfoMU,824
2
- checkpointer/checkpoint.py,sha256=zU67_PGrVCMP90clPTR7AA4vfxECqmeFr0jJElUL5iQ,9051
3
- checkpointer/fn_ident.py,sha256=-5XbovQowVyYCFc7JdT9z1NoIEiL8h9fi7alF_34Ils,4470
4
- checkpointer/object_hash.py,sha256=YlyFupQrg3V2mpzTLfOqpqlZWhoSCHliScQ4cKd36T0,8133
5
- checkpointer/print_checkpoint.py,sha256=aJCeWMRJiIR3KpyPk_UOKTaD906kArGrmLGQ3LqcVgo,1369
6
- checkpointer/test_checkpointer.py,sha256=-EvsMMNOOiIxhTcG97LLX0jUMWp534ko7qCKDSFWiA0,3802
7
- checkpointer/types.py,sha256=rAdjZNn1-jk35df7UVtby_qlp-8_18ucXfVCtS4RI_M,323
8
- checkpointer/utils.py,sha256=0cGVSlTnABgs3jI1uHoTfz353kkGa-qtTfe7jG4NCr0,2192
9
- checkpointer/storages/__init__.py,sha256=en32nTUltpCSgz8RVGS_leIHC1Y1G89IqG1ZqAb6qUo,236
10
- checkpointer/storages/memory_storage.py,sha256=Br30b1AyNOcNjjAaDui1mBjDKfhDbu--jV4WmJenzaE,1109
11
- checkpointer/storages/pickle_storage.py,sha256=xS96q8TvwxH_TOZsiKmrMrhFwQKZCcaH7XOiECmuwl8,1628
12
- checkpointer/storages/storage.py,sha256=5NWmnfsU2QY24NwKC5MZNe4h7pcYhADw-y800v17aYE,895
13
- checkpointer-2.11.0.dist-info/METADATA,sha256=GFRKdyTOIQwvmzIIrkV2owT8NO-X2ONRXdnadY9j5xY,11617
14
- checkpointer-2.11.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
15
- checkpointer-2.11.0.dist-info/licenses/LICENSE,sha256=9xVsdtv_-uSyY9Xl9yujwAPm4-mjcCLeVy-ljwXEWbo,1059
16
- checkpointer-2.11.0.dist-info/RECORD,,