checkpointer 2.14.1__py3-none-any.whl → 2.14.3__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.
@@ -12,8 +12,8 @@ from .fn_ident import Capturable, RawFunctionIdent, get_fn_ident
12
12
  from .object_hash import ObjectHash
13
13
  from .print_checkpoint import print_checkpoint
14
14
  from .storages import STORAGE_MAP, Storage, StorageType
15
- from .types import AwaitableValue, C, Coro, Fn, P, R, hash_by_from_annotation
16
- from .utils import flatten
15
+ from .types import AwaitableValue, C, Coro, Fn, P, R, T, hash_by_from_annotation
16
+ from .utils import flatten, to_coroutine
17
17
 
18
18
  DEFAULT_DIR = Path.home() / ".cache/checkpoints"
19
19
 
@@ -211,6 +211,8 @@ class CachedFunction(Generic[Fn]):
211
211
  try:
212
212
  data = storage.load(call_hash)
213
213
  print_checkpoint(params.verbosity >= 2, "REMEMBERED", call_id, "green")
214
+ if isinstance(data, AwaitableValue):
215
+ return to_coroutine(data.value) # type: ignore
214
216
  return data
215
217
  except (EOFError, FileNotFoundError):
216
218
  pass
@@ -241,6 +243,16 @@ class CachedFunction(Generic[Fn]):
241
243
  except Exception as ex:
242
244
  raise CheckpointError("Could not load checkpoint") from ex
243
245
 
246
+ @overload
247
+ def get_or(self: Callable[P, Coro[R]], default: T, *args: P.args, **kw: P.kwargs) -> R | T: ...
248
+ @overload
249
+ def get_or(self: Callable[P, R], default: T, *args: P.args, **kw: P.kwargs) -> R | T: ...
250
+ def get_or(self, default, *args, **kw):
251
+ try:
252
+ return self.get(*args, **kw) # type: ignore
253
+ except CheckpointError:
254
+ return default
255
+
244
256
  @overload
245
257
  def set(self: Callable[P, Coro[R]], value: AwaitableValue[R], *args: P.args, **kw: P.kwargs): ...
246
258
  @overload
@@ -1,22 +1,26 @@
1
1
  import pickle
2
2
  import shutil
3
3
  from datetime import datetime
4
+ from io import BytesIO
4
5
  from pathlib import Path
6
+ from ..utils import clear_directory
5
7
  from .storage import Storage
6
8
 
9
+ try:
10
+ import polars as pl
11
+ except:
12
+ pl = None
13
+
7
14
  def filedate(path: Path) -> datetime:
8
15
  return datetime.fromtimestamp(path.stat().st_mtime)
9
16
 
10
- def empty_dirs(path: Path):
11
- nonempty_count = 0
12
- for child in path.iterdir():
13
- nonempty_count += 1
14
- if child.is_dir():
15
- for grand_child in empty_dirs(child):
16
- yield grand_child
17
- nonempty_count -= child == grand_child
18
- if nonempty_count == 0:
19
- yield path
17
+ class ExtendedPickler(pickle.Pickler):
18
+ def reducer_override(self, obj): # type: ignore
19
+ if pl and isinstance(obj, pl.DataFrame):
20
+ buffer = BytesIO()
21
+ obj.rechunk().write_parquet(buffer)
22
+ return pl.read_parquet, (buffer.getvalue(),)
23
+ return NotImplemented
20
24
 
21
25
  class PickleStorage(Storage):
22
26
  def get_path(self, call_hash: str):
@@ -26,7 +30,7 @@ class PickleStorage(Storage):
26
30
  path = self.get_path(call_hash)
27
31
  path.parent.mkdir(parents=True, exist_ok=True)
28
32
  with path.open("wb") as file:
29
- pickle.dump(data, file, -1)
33
+ ExtendedPickler(file, -1).dump(data)
30
34
  return data
31
35
 
32
36
  def exists(self, call_hash):
@@ -58,11 +62,7 @@ class PickleStorage(Storage):
58
62
  count += 1
59
63
  pkl_path.unlink(missing_ok=True)
60
64
  print(f"Removed {count} expired checkpoints for {self.cached_fn.__qualname__}")
61
- if fn_path.exists():
62
- for file in fn_path.glob("**/.DS_Store"):
63
- file.unlink()
64
- for directory in empty_dirs(fn_path):
65
- directory.rmdir()
65
+ clear_directory(fn_path)
66
66
 
67
67
  def clear(self):
68
68
  fn_path = self.fn_dir().parent
checkpointer/utils.py CHANGED
@@ -10,6 +10,9 @@ from .types import T
10
10
  cwd = Path.cwd().resolve()
11
11
  flatten = chain.from_iterable
12
12
 
13
+ async def to_coroutine(value: T) -> T:
14
+ return value
15
+
13
16
  def is_class(obj) -> TypeGuard[Type]:
14
17
  return isinstance(obj, type)
15
18
 
@@ -112,3 +115,21 @@ class ContextVar(Generic[T]):
112
115
  yield
113
116
  finally:
114
117
  self.value = old
118
+
119
+ def empty_dirs(path: Path) -> Iterable[Path]:
120
+ nonempty_count = 0
121
+ for child in path.iterdir():
122
+ nonempty_count += 1
123
+ if child.is_dir():
124
+ for grand_child in empty_dirs(child):
125
+ yield grand_child
126
+ nonempty_count -= child == grand_child
127
+ if nonempty_count == 0:
128
+ yield path
129
+
130
+ def clear_directory(path: Path):
131
+ if path.is_dir():
132
+ for file in path.glob("**/.DS_Store"):
133
+ file.unlink()
134
+ for directory in empty_dirs(path):
135
+ directory.rmdir()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: checkpointer
3
- Version: 2.14.1
3
+ Version: 2.14.3
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
@@ -1,18 +1,18 @@
1
1
  checkpointer/__init__.py,sha256=mT706hd-BoTpQXYH_MiqreplONVDvjCWjwwGQ7oRe_8,921
2
- checkpointer/checkpoint.py,sha256=SUHu5ADRtSrapspk2DpBLaYnAQ7yuTc05lUELig_Tpc,9972
2
+ checkpointer/checkpoint.py,sha256=N3MtNF4Oq3FV69LCfIuyTfNxrcnw9-dGzX312eYigVQ,10454
3
3
  checkpointer/fn_ident.py,sha256=Z2HtkoG8n0ddqNzjejnKW6Lo-ID2unKQZa1tOpRGujs,6911
4
4
  checkpointer/fn_string.py,sha256=YldjAU91cwiZNwuE_AQN_DMiQCPAhGiiC3lPi0uvM0g,2579
5
5
  checkpointer/import_mappings.py,sha256=ESqWvZTzYAmaVnJ6NulUvn3_8CInOOPmEKUXO2WD_WA,1794
6
6
  checkpointer/object_hash.py,sha256=_VgyTEoe3H6268KBAOFZxSgWHb6otgG-3NzhHyehxe4,8595
7
7
  checkpointer/print_checkpoint.py,sha256=uUQ493fJCaB4nhp4Ox60govSCiBTIPbBX15zt2QiRGo,1356
8
8
  checkpointer/types.py,sha256=GFqbGACdDxzQX3bb2LmF9UxQVWOEisGvdtobnqCBAOA,1129
9
- checkpointer/utils.py,sha256=CF28pGytCWV4URhRDFaIDawX8qmCAAByQp0ZkEwrA6c,3014
9
+ checkpointer/utils.py,sha256=BAv_qvcanbYqgr7cCOCKNiG0_rGbNbLomBbpvoYlltc,3553
10
10
  checkpointer/storages/__init__.py,sha256=p-r4YrPXn505_S3qLrSXHSlsEtb13w_DFnCt9IiUomk,296
11
11
  checkpointer/storages/memory_storage.py,sha256=1YHZU-WSqvLA_0og53UZY141ziDgnaBub2mDjDaeAj8,1261
12
- checkpointer/storages/pickle_storage.py,sha256=PwFbCqYHjR3jiWuTnwxCU9cui7CINvq0wXIOKtf8dOk,2230
12
+ checkpointer/storages/pickle_storage.py,sha256=WCbWGdDH046_GrlnttcqqGZ55wGOz2Rb7Gu0slI448g,2203
13
13
  checkpointer/storages/storage.py,sha256=JVxdq1DMhbq83bvflvIuW7okE1CQCa7poQPsj3x0ACg,1366
14
- checkpointer-2.14.1.dist-info/METADATA,sha256=KupseJCcWRNym_Ckit_F-oGLPIgqUsyKJvjl6ekEDZU,11215
15
- checkpointer-2.14.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- checkpointer-2.14.1.dist-info/licenses/ATTRIBUTION.md,sha256=WF6L7-sD4s9t9ytVJOhjhpDoZ6TrWpqE3_bMdDIeJxI,1078
17
- checkpointer-2.14.1.dist-info/licenses/LICENSE,sha256=drXs6vIb7uW49r70UuMz2A1VtOCl626kiTbcmrar1Xo,1072
18
- checkpointer-2.14.1.dist-info/RECORD,,
14
+ checkpointer-2.14.3.dist-info/METADATA,sha256=YehES3ivV7IqJfs3jKVNCfrgRZwdEySFJrwqem8MVPo,11215
15
+ checkpointer-2.14.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ checkpointer-2.14.3.dist-info/licenses/ATTRIBUTION.md,sha256=WF6L7-sD4s9t9ytVJOhjhpDoZ6TrWpqE3_bMdDIeJxI,1078
17
+ checkpointer-2.14.3.dist-info/licenses/LICENSE,sha256=drXs6vIb7uW49r70UuMz2A1VtOCl626kiTbcmrar1Xo,1072
18
+ checkpointer-2.14.3.dist-info/RECORD,,