checkpointer 2.14.4__tar.gz → 2.14.6__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.4 → checkpointer-2.14.6}/PKG-INFO +1 -1
  2. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/checkpoint.py +10 -4
  3. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/storages/memory_storage.py +16 -6
  4. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/storages/pickle_storage.py +6 -3
  5. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/storages/storage.py +4 -4
  6. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/utils.py +4 -4
  7. {checkpointer-2.14.4 → checkpointer-2.14.6}/pyproject.toml +2 -2
  8. {checkpointer-2.14.4 → checkpointer-2.14.6}/uv.lock +5 -5
  9. {checkpointer-2.14.4 → checkpointer-2.14.6}/.gitignore +0 -0
  10. {checkpointer-2.14.4 → checkpointer-2.14.6}/.python-version +0 -0
  11. {checkpointer-2.14.4 → checkpointer-2.14.6}/ATTRIBUTION.md +0 -0
  12. {checkpointer-2.14.4 → checkpointer-2.14.6}/LICENSE +0 -0
  13. {checkpointer-2.14.4 → checkpointer-2.14.6}/README.md +0 -0
  14. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/__init__.py +0 -0
  15. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/fn_ident.py +0 -0
  16. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/fn_string.py +0 -0
  17. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/import_mappings.py +0 -0
  18. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/object_hash.py +0 -0
  19. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/print_checkpoint.py +0 -0
  20. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/storages/__init__.py +0 -0
  21. {checkpointer-2.14.4 → checkpointer-2.14.6}/checkpointer/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: checkpointer
3
- Version: 2.14.4
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
@@ -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] | timedelta | None
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
- memory_stores = [obj for obj in gc.get_objects() if isinstance(obj, MemoryStorage)]
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 memory_stores:
53
- store.cleanup(invalidated=False)
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
- shutil.rmtree(path)
57
- print(f"Removed {len(old_dirs)} invalidated directories for {self.cached_fn.__qualname__}")
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
- print(f"Removed {count} expired checkpoints for {self.cached_fn.__qualname__}")
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):
@@ -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 Checkpointer, CachedFunction
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 not self.checkpointer.expiry:
25
+ if self.checkpointer.expiry is None:
26
26
  return False
27
27
  return self.expired_dt(self.checkpoint_date(call_hash))
28
28
 
@@ -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 grand_child in empty_dirs(child):
125
- yield grand_child
126
- nonempty_count -= child == grand_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
  [project]
2
2
  name = "checkpointer"
3
- version = "2.14.4"
3
+ version = "2.14.6"
4
4
  requires-python = ">=3.11"
5
5
  dependencies = []
6
6
  authors = [
@@ -36,7 +36,7 @@ Repository = "https://github.com/Reddan/checkpointer.git"
36
36
  [dependency-groups]
37
37
  dev = [
38
38
  "numpy>=2.2.1",
39
- "omg>=1.3.6",
39
+ "omg>=1.3.9",
40
40
  "poethepoet>=0.30.0",
41
41
  "polars>=1.31.0",
42
42
  "pytest>=8.3.5",
@@ -8,7 +8,7 @@ resolution-markers = [
8
8
 
9
9
  [[package]]
10
10
  name = "checkpointer"
11
- version = "2.14.4"
11
+ version = "2.14.6"
12
12
  source = { editable = "." }
13
13
 
14
14
  [package.dev-dependencies]
@@ -28,7 +28,7 @@ dev = [
28
28
  [package.metadata.requires-dev]
29
29
  dev = [
30
30
  { name = "numpy", specifier = ">=2.2.1" },
31
- { name = "omg", specifier = ">=1.3.6" },
31
+ { name = "omg", specifier = ">=1.3.9" },
32
32
  { name = "poethepoet", specifier = ">=0.30.0" },
33
33
  { name = "polars", specifier = ">=1.31.0" },
34
34
  { name = "pytest", specifier = ">=8.3.5" },
@@ -340,14 +340,14 @@ wheels = [
340
340
 
341
341
  [[package]]
342
342
  name = "omg"
343
- version = "1.3.6"
343
+ version = "1.3.9"
344
344
  source = { registry = "https://pypi.org/simple" }
345
345
  dependencies = [
346
346
  { name = "watchdog" },
347
347
  ]
348
- sdist = { url = "https://files.pythonhosted.org/packages/65/06/da0a3778b7ff8f1333ed7ddc0931ffff3c86ab5cb8bc4a96a1d0edb8671b/omg-1.3.6.tar.gz", hash = "sha256:465a51b7576fa31ef313e2b9a77d57f5d4816fb0a14dca0fc5c09ff471074fe6", size = 14268 }
348
+ sdist = { url = "https://files.pythonhosted.org/packages/2a/a3/4a0fb81ac8265c688dbd8eddc4ac61d0621a850a1037090d4af88ae38f01/omg-1.3.9.tar.gz", hash = "sha256:4d2de31323a8b2bfd80e04e1670b8d3a5912cec041854bcae79a97fb10f0b7ea", size = 14683 }
349
349
  wheels = [
350
- { url = "https://files.pythonhosted.org/packages/dd/d2/87346e94dbecd3a65a09e2156c1adf30c162f31e69d0936343c3eff53e7a/omg-1.3.6-py3-none-any.whl", hash = "sha256:8e3ac99a18d5284ceef2ed98492d288d5f22ee2bb417591654a7d2433e196607", size = 7988 },
350
+ { url = "https://files.pythonhosted.org/packages/f8/44/0f768cb8c82a5ed4ae5a71246668be55351795cc4438045425bd9709099a/omg-1.3.9-py3-none-any.whl", hash = "sha256:585abf178a28749c1b80bbba154914a9cfeb688b3955883d72068e2726716c8a", size = 8121 },
351
351
  ]
352
352
 
353
353
  [[package]]
File without changes
File without changes
File without changes