persistent-function-cache 0.1.0__tar.gz → 0.1.1__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.
- {persistent_function_cache-0.1.0/src/persistent_function_cache.egg-info → persistent_function_cache-0.1.1}/PKG-INFO +3 -3
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/README.md +1 -1
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/pyproject.toml +2 -4
- persistent_function_cache-0.1.1/src/persistent_cache/__init__.py +2 -0
- persistent_function_cache-0.1.1/src/persistent_cache/caches/deep_learning.py +18 -0
- persistent_function_cache-0.1.1/src/persistent_cache/caches/speedup_deep_learning.py +18 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/main/decorator.py +24 -5
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/main/hashing.py +21 -10
- persistent_function_cache-0.1.1/src/persistent_cache/models/__init__.py +2 -0
- persistent_function_cache-0.1.1/src/persistent_cache/models/function.py +4 -0
- persistent_function_cache-0.1.1/src/persistent_cache/reducers/__init__.py +1 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/reducers/speedup_deep_learning.py +1 -1
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1/src/persistent_function_cache.egg-info}/PKG-INFO +3 -3
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_function_cache.egg-info/SOURCES.txt +3 -2
- persistent_function_cache-0.1.1/tests/test_cache.py +33 -0
- persistent_function_cache-0.1.1/tests/test_deep_learning_cache.py +34 -0
- persistent_function_cache-0.1.0/src/persistent_cache/__init__.py +0 -1
- persistent_function_cache-0.1.0/src/persistent_cache/caches/base.py +0 -4
- persistent_function_cache-0.1.0/src/persistent_cache/caches/deep_learning.py +0 -4
- persistent_function_cache-0.1.0/src/persistent_cache/caches/speedup_deep_learning.py +0 -4
- persistent_function_cache-0.1.0/src/persistent_cache/models/__init__.py +0 -1
- persistent_function_cache-0.1.0/src/persistent_cache/reducers/__init__.py +0 -0
- persistent_function_cache-0.1.0/tests/test_cache.py +0 -26
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/LICENSE +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/setup.cfg +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/caches/__init__.py +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/cli/__init__.py +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/cli/clear_cache.py +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/main/__init__.py +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/main/cacheslot.py +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/models/path.py +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/py.typed +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/reducers/base.py +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/reducers/deep_learning.py +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_function_cache.egg-info/dependency_links.txt +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_function_cache.egg-info/entry_points.txt +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_function_cache.egg-info/requires.txt +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_function_cache.egg-info/top_level.txt +0 -0
- {persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/tests/test_clear_cache.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: persistent-function-cache
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Persistent cache for expensive functions
|
|
5
5
|
Author-email: Quinten Roets <qdr2104@columbia.edu>
|
|
6
6
|
License: MIT
|
|
@@ -22,7 +22,7 @@ Requires-Dist: torch<3,>=1.26.0; extra == "dev"
|
|
|
22
22
|

|
|
23
23
|

|
|
24
24
|

|
|
25
|
-

|
|
26
26
|
|
|
27
27
|
## Usage
|
|
28
28
|
Use
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|

|
|
4
4
|

|
|
5
5
|

|
|
6
|
-

|
|
7
7
|
|
|
8
8
|
## Usage
|
|
9
9
|
Use
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "persistent-function-cache"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.1"
|
|
4
4
|
description = "Persistent cache for expensive functions"
|
|
5
5
|
authors = [{name = "Quinten Roets", email = "qdr2104@columbia.edu"}]
|
|
6
6
|
license = {text = "MIT"}
|
|
@@ -35,7 +35,7 @@ command_line = "-m pytest tests"
|
|
|
35
35
|
|
|
36
36
|
[tool.coverage.report]
|
|
37
37
|
precision = 4
|
|
38
|
-
fail_under =
|
|
38
|
+
fail_under = 100
|
|
39
39
|
|
|
40
40
|
[tool.mypy]
|
|
41
41
|
strict = true
|
|
@@ -52,8 +52,6 @@ fix = true
|
|
|
52
52
|
[tool.ruff.lint]
|
|
53
53
|
select = ["ALL"]
|
|
54
54
|
ignore = [
|
|
55
|
-
"ANN101", # annotate self
|
|
56
|
-
"ANN102", # annotate cls
|
|
57
55
|
"ANN401", # annotated with Any
|
|
58
56
|
"D", # docstrings
|
|
59
57
|
"G004", # logging f-string
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
|
|
3
|
+
from persistent_cache.main import decorator
|
|
4
|
+
from persistent_cache.models import F, Path
|
|
5
|
+
from persistent_cache.reducers import Reducer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def cache(
|
|
9
|
+
function: F | None = None,
|
|
10
|
+
*,
|
|
11
|
+
key_reducer: type[Reducer] | None = None,
|
|
12
|
+
cache_path: Path = Path.cache,
|
|
13
|
+
) -> Callable[[F], F]:
|
|
14
|
+
if key_reducer is None:
|
|
15
|
+
from persistent_cache.reducers import deep_learning
|
|
16
|
+
|
|
17
|
+
key_reducer = deep_learning.Reducer
|
|
18
|
+
return decorator.cache(function, key_reducer=key_reducer, cache_path=cache_path)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
|
|
3
|
+
from persistent_cache.main import decorator
|
|
4
|
+
from persistent_cache.models import F, Path
|
|
5
|
+
from persistent_cache.reducers import Reducer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def cache(
|
|
9
|
+
function: F | None = None,
|
|
10
|
+
*,
|
|
11
|
+
key_reducer: type[Reducer] | None = None,
|
|
12
|
+
cache_path: Path = Path.cache,
|
|
13
|
+
) -> Callable[[F], F]:
|
|
14
|
+
if key_reducer is None:
|
|
15
|
+
from persistent_cache.reducers import speedup_deep_learning
|
|
16
|
+
|
|
17
|
+
key_reducer = speedup_deep_learning.Reducer
|
|
18
|
+
return decorator.cache(function, key_reducer=key_reducer, cache_path=cache_path)
|
|
@@ -1,20 +1,37 @@
|
|
|
1
1
|
from collections.abc import Callable
|
|
2
2
|
from functools import wraps
|
|
3
|
-
from typing import Any,
|
|
3
|
+
from typing import Any, cast, overload
|
|
4
4
|
|
|
5
|
-
from persistent_cache.models import Path
|
|
5
|
+
from persistent_cache.models import F, Path
|
|
6
6
|
from persistent_cache.reducers.base import Reducer
|
|
7
7
|
|
|
8
8
|
from .cacheslot import CacheSlot
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
|
|
11
|
+
@overload
|
|
12
|
+
def cache(
|
|
13
|
+
function: F,
|
|
14
|
+
*,
|
|
15
|
+
key_reducer: type[Reducer] = Reducer,
|
|
16
|
+
cache_path: Path = Path.cache,
|
|
17
|
+
) -> F: ...
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@overload
|
|
21
|
+
def cache(
|
|
22
|
+
function: None = None,
|
|
23
|
+
*,
|
|
24
|
+
key_reducer: type[Reducer] = Reducer,
|
|
25
|
+
cache_path: Path = Path.cache,
|
|
26
|
+
) -> Callable[[F], F]: ...
|
|
12
27
|
|
|
13
28
|
|
|
14
29
|
def cache(
|
|
30
|
+
function: F | None = None,
|
|
31
|
+
*,
|
|
15
32
|
key_reducer: type[Reducer] = Reducer,
|
|
16
33
|
cache_path: Path = Path.cache,
|
|
17
|
-
) -> Callable[[F], F]:
|
|
34
|
+
) -> F | Callable[[F], F]:
|
|
18
35
|
"""A decorator to cache function results. Decorated functions are only executed if
|
|
19
36
|
result is not present in cache. The arguments of the function can be any nested
|
|
20
37
|
complex object.
|
|
@@ -41,4 +58,6 @@ def cache(
|
|
|
41
58
|
|
|
42
59
|
return cast(F, wrapped_function)
|
|
43
60
|
|
|
61
|
+
if function is not None:
|
|
62
|
+
cache_decorator = cache_decorator(function)
|
|
44
63
|
return cache_decorator
|
|
@@ -4,13 +4,28 @@ import hashlib
|
|
|
4
4
|
import inspect
|
|
5
5
|
import io
|
|
6
6
|
import pickle
|
|
7
|
-
from
|
|
7
|
+
from types import UnionType
|
|
8
|
+
from typing import TYPE_CHECKING, Any, get_args, get_origin, get_type_hints
|
|
8
9
|
|
|
9
10
|
from persistent_cache.reducers.base import Reducer
|
|
10
11
|
|
|
11
12
|
if TYPE_CHECKING:
|
|
12
|
-
from collections.abc import Callable, Iterator
|
|
13
|
-
from typing import BinaryIO
|
|
13
|
+
from collections.abc import Callable, Iterator # pragma: nocover
|
|
14
|
+
from typing import BinaryIO # pragma: nocover
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def extract_types(method: Callable[[Any], Any]) -> Iterator[type]:
|
|
18
|
+
type_hints = get_type_hints(method).values()
|
|
19
|
+
if type_hints:
|
|
20
|
+
argument_type = next(iter(type_hints))
|
|
21
|
+
origin = get_origin(argument_type)
|
|
22
|
+
arguments = get_args(argument_type)
|
|
23
|
+
if origin is UnionType:
|
|
24
|
+
yield from arguments
|
|
25
|
+
elif origin is not None:
|
|
26
|
+
yield origin
|
|
27
|
+
else:
|
|
28
|
+
yield argument_type
|
|
14
29
|
|
|
15
30
|
|
|
16
31
|
class HashPickler(pickle.Pickler):
|
|
@@ -23,13 +38,9 @@ class HashPickler(pickle.Pickler):
|
|
|
23
38
|
self.reducer = reducer
|
|
24
39
|
self.reducers = {}
|
|
25
40
|
for _, method in inspect.getmembers(reducer, predicate=inspect.ismethod):
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
argument_type =
|
|
29
|
-
argument_types = get_args(argument_type) or (argument_type,)
|
|
30
|
-
for argument_type in argument_types:
|
|
31
|
-
self.reducers[argument_type] = method
|
|
32
|
-
self.reducers.pop(Any, None)
|
|
41
|
+
argument_types = extract_types(method)
|
|
42
|
+
for argument_type in argument_types:
|
|
43
|
+
self.reducers[argument_type] = method
|
|
33
44
|
|
|
34
45
|
def reducer_override(self, obj: Any) -> Any:
|
|
35
46
|
"""The goal of this pickler is to create hashes of complex objects, not to
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .base import Reducer
|
|
@@ -51,7 +51,7 @@ class Reducer(deep_learning.Reducer):
|
|
|
51
51
|
|
|
52
52
|
# only use part of dataset for speedup
|
|
53
53
|
data = dataset[13**17 % length] if length > 0 else []
|
|
54
|
-
if isinstance(data, tuple):
|
|
54
|
+
if isinstance(data, tuple) and len(data) == 2: # noqa: PLR2004
|
|
55
55
|
data, label = data
|
|
56
56
|
else:
|
|
57
57
|
label = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: persistent-function-cache
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Persistent cache for expensive functions
|
|
5
5
|
Author-email: Quinten Roets <qdr2104@columbia.edu>
|
|
6
6
|
License: MIT
|
|
@@ -22,7 +22,7 @@ Requires-Dist: torch<3,>=1.26.0; extra == "dev"
|
|
|
22
22
|

|
|
23
23
|

|
|
24
24
|

|
|
25
|
-

|
|
26
26
|
|
|
27
27
|
## Usage
|
|
28
28
|
Use
|
|
@@ -4,7 +4,6 @@ pyproject.toml
|
|
|
4
4
|
src/persistent_cache/__init__.py
|
|
5
5
|
src/persistent_cache/py.typed
|
|
6
6
|
src/persistent_cache/caches/__init__.py
|
|
7
|
-
src/persistent_cache/caches/base.py
|
|
8
7
|
src/persistent_cache/caches/deep_learning.py
|
|
9
8
|
src/persistent_cache/caches/speedup_deep_learning.py
|
|
10
9
|
src/persistent_cache/cli/__init__.py
|
|
@@ -14,6 +13,7 @@ src/persistent_cache/main/cacheslot.py
|
|
|
14
13
|
src/persistent_cache/main/decorator.py
|
|
15
14
|
src/persistent_cache/main/hashing.py
|
|
16
15
|
src/persistent_cache/models/__init__.py
|
|
16
|
+
src/persistent_cache/models/function.py
|
|
17
17
|
src/persistent_cache/models/path.py
|
|
18
18
|
src/persistent_cache/reducers/__init__.py
|
|
19
19
|
src/persistent_cache/reducers/base.py
|
|
@@ -26,4 +26,5 @@ src/persistent_function_cache.egg-info/entry_points.txt
|
|
|
26
26
|
src/persistent_function_cache.egg-info/requires.txt
|
|
27
27
|
src/persistent_function_cache.egg-info/top_level.txt
|
|
28
28
|
tests/test_cache.py
|
|
29
|
-
tests/test_clear_cache.py
|
|
29
|
+
tests/test_clear_cache.py
|
|
30
|
+
tests/test_deep_learning_cache.py
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import math
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import cli
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
from persistent_cache import cache, deep_learning, speedup_deep_learning
|
|
10
|
+
|
|
11
|
+
caches = [cache, deep_learning.cache, speedup_deep_learning.cache]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def calculate(*args: Any, **kwargs: Any) -> None:
|
|
15
|
+
cli.console.print("calculation started")
|
|
16
|
+
cli.console.print(args, kwargs)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def verify_cached_function(function: Callable[..., Any]) -> None:
|
|
20
|
+
with io.BytesIO() as fp:
|
|
21
|
+
function(fp, lambda x: x, math, {})
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@pytest.mark.parametrize("cache_decorator", caches)
|
|
25
|
+
def test_cache_with_argument_combination(cache_decorator: Callable[..., Any]) -> None:
|
|
26
|
+
cached_function = cache_decorator(calculate)
|
|
27
|
+
verify_cached_function(cached_function)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@pytest.mark.parametrize("cache_decorator", caches)
|
|
31
|
+
def test_cache_as_function(cache_decorator: Callable[..., Any]) -> None:
|
|
32
|
+
cached_function = cache_decorator()(calculate)
|
|
33
|
+
verify_cached_function(cached_function)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import cli
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pytest
|
|
7
|
+
import torch
|
|
8
|
+
from torch.utils.data import TensorDataset
|
|
9
|
+
|
|
10
|
+
from persistent_cache import deep_learning, speedup_deep_learning
|
|
11
|
+
from persistent_cache.reducers.speedup_deep_learning import LARGE_DIMENSION
|
|
12
|
+
|
|
13
|
+
caches = [deep_learning.cache, speedup_deep_learning.cache]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def calculate(*args: Any, **kwargs: Any) -> None:
|
|
17
|
+
cli.console.print("calculation started")
|
|
18
|
+
cli.console.print(args, kwargs)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def verify_cached_function(function: Callable[..., Any]) -> None:
|
|
22
|
+
array = np.zeros(10)
|
|
23
|
+
large_array = np.zeros((10, LARGE_DIMENSION))
|
|
24
|
+
tensor = torch.tensor(array)
|
|
25
|
+
module = torch.nn.Linear(10, 2)
|
|
26
|
+
dataset = TensorDataset(tensor)
|
|
27
|
+
labeled_dataset = TensorDataset(tensor, tensor)
|
|
28
|
+
function(array, tensor, module, dataset, large_array, labeled_dataset)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.mark.parametrize("cache_decorator", caches)
|
|
32
|
+
def test_cache_with_argument_combination(cache_decorator: Callable[..., Any]) -> None:
|
|
33
|
+
cached_function = cache_decorator(calculate)
|
|
34
|
+
verify_cached_function(cached_function)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .caches.base import cache
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .path import Path
|
|
File without changes
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import io
|
|
2
|
-
import math
|
|
3
|
-
from collections.abc import Callable
|
|
4
|
-
from typing import Any, TypeVar
|
|
5
|
-
|
|
6
|
-
import cli
|
|
7
|
-
import pytest
|
|
8
|
-
|
|
9
|
-
from persistent_cache.caches import base, deep_learning, speedup_deep_learning
|
|
10
|
-
|
|
11
|
-
F = TypeVar("F", bound=Callable) # type: ignore[type-arg]
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def calculate(*args: Any, **kwargs: Any) -> None:
|
|
15
|
-
cli.console.print("calculation started")
|
|
16
|
-
cli.console.print(args, kwargs)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
caches = [base.cache, deep_learning.cache, speedup_deep_learning.cache]
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@pytest.mark.parametrize("cache", caches)
|
|
23
|
-
def test_cache_with_argument_combination(cache: Callable) -> None: # type: ignore[type-arg]
|
|
24
|
-
cached_function = cache(calculate)
|
|
25
|
-
with io.BytesIO() as fp:
|
|
26
|
-
cached_function(fp, lambda x: x, math, {})
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/src/persistent_cache/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persistent_function_cache-0.1.0 → persistent_function_cache-0.1.1}/tests/test_clear_cache.py
RENAMED
|
File without changes
|