pickle-debug 1.2__tar.gz → 2.0__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.
- {pickle_debug-1.2/src/pickle_debug.egg-info → pickle_debug-2.0}/PKG-INFO +37 -5
- {pickle_debug-1.2 → pickle_debug-2.0}/README.md +36 -4
- {pickle_debug-1.2 → pickle_debug-2.0}/pyproject.toml +1 -1
- {pickle_debug-1.2 → pickle_debug-2.0/src/pickle_debug.egg-info}/PKG-INFO +37 -5
- {pickle_debug-1.2 → pickle_debug-2.0}/src/pickle_debug.egg-info/SOURCES.txt +1 -3
- pickle_debug-1.2/src/test/record.py +0 -11
- pickle_debug-1.2/src/test/unpicklable_test.py +0 -46
- {pickle_debug-1.2 → pickle_debug-2.0}/LICENSE +0 -0
- {pickle_debug-1.2 → pickle_debug-2.0}/setup.cfg +0 -0
- {pickle_debug-1.2 → pickle_debug-2.0}/src/pickle_debug/__init__.py +0 -0
- {pickle_debug-1.2 → pickle_debug-2.0}/src/pickle_debug.egg-info/dependency_links.txt +0 -0
- {pickle_debug-1.2 → pickle_debug-2.0}/src/pickle_debug.egg-info/top_level.txt +0 -0
- {pickle_debug-1.2 → pickle_debug-2.0}/src/test/patch_test.py +0 -0
- {pickle_debug-1.2 → pickle_debug-2.0}/src/test/pd_test.py +0 -0
- {pickle_debug-1.2 → pickle_debug-2.0}/src/test/ttest.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pickle_debug
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0
|
|
4
4
|
Summary: Store expensive objects from debugging
|
|
5
5
|
Author: Gerard
|
|
6
6
|
Author-email: gweatherby@uchc.edu
|
|
@@ -59,6 +59,35 @@ slow.invoke = pickle_debug.cached(slow.invoke) # one instance
|
|
|
59
59
|
Slow.invoke = pickle_debug.cached(Slow.invoke) # all instances
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
The decorator also works inside a class body. For a classmethod, put `@cached` below `@classmethod`:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
class Slow:
|
|
66
|
+
@pickle_debug.cached
|
|
67
|
+
def invoke(self, x):
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
@pickle_debug.cached
|
|
72
|
+
def build(cls, x):
|
|
73
|
+
...
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
A wrapper may be needed to cache some functions, e.g. a method returning a generator:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
def something(x,y,z)->Generator:
|
|
80
|
+
|
|
81
|
+
@pickle_debug.cached
|
|
82
|
+
def cache_something(x,y,z)->list:
|
|
83
|
+
return list(something(x,y,z))
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
When a cached function is called as a method, `self` (or `cls`) is keyed by its class's name
|
|
87
|
+
(`module.QualifiedName`), not its current value. All instances of a class share cache entries, and the
|
|
88
|
+
instance does not need to be picklable. Subclasses get their own entries. Static methods are keyed like
|
|
89
|
+
plain functions.
|
|
90
|
+
|
|
62
91
|
## API
|
|
63
92
|
|
|
64
93
|
### `enable(directory)`
|
|
@@ -70,7 +99,8 @@ Decorator. Returns a wrapper (using `functools.wraps`) that:
|
|
|
70
99
|
|
|
71
100
|
1. calls `func` directly if caching is not enabled;
|
|
72
101
|
2. otherwise builds a key from `func.__module__`, `func.__qualname__`, the positional arguments and
|
|
73
|
-
the sorted keyword arguments, and hashes it with SHA-256
|
|
102
|
+
the sorted keyword arguments, and hashes it with SHA-256. If `func` is called as a method, the
|
|
103
|
+
first argument (`self` or `cls`) is replaced by its class's name (see [Methods](#methods));
|
|
74
104
|
3. returns the pickled result from `<directory>/<hash>.pickle` if present;
|
|
75
105
|
4. otherwise calls `func`, writes the result to the cache, and returns it.
|
|
76
106
|
|
|
@@ -101,13 +131,15 @@ wrong place. It does nothing if caching is not enabled or the directory does not
|
|
|
101
131
|
[Unpicklable attributes](#unpicklable-attributes)). The arguments are pickled to build the key, and the
|
|
102
132
|
result is pickled to store it. Because dropped attributes are not part of the key, two arguments that
|
|
103
133
|
differ only in unpicklable attributes share a cache entry.
|
|
134
|
+
- **Wrappers may be required** for methods that return generators.
|
|
104
135
|
- **The key is the pickled arguments.** Equal arguments that pickle differently (for example sets with a
|
|
105
136
|
different iteration order) may miss the cache. Objects whose pickle changes between calls never hit it.
|
|
106
137
|
- **The key does not include the function's code or any files it reads.** If you change the function or
|
|
107
138
|
its input data, call `reset()` or use a new cache directory, or you will get stale results.
|
|
108
|
-
- **
|
|
109
|
-
so all instances share entries.
|
|
110
|
-
|
|
139
|
+
- **Instance state is not part of the key.** Methods are keyed by the class of `self` or `cls`, not by its
|
|
140
|
+
value, so all instances of a class share entries. If a method's result depends on instance attributes,
|
|
141
|
+
instances with different state will get each other's cached results. Pass that state as an argument
|
|
142
|
+
instead, or call `reset()` between runs.
|
|
111
143
|
- This is a debugging aid. Do not use it as a production cache. Cached files are loaded with `pickle`,
|
|
112
144
|
so only use a directory you trust.
|
|
113
145
|
|
|
@@ -47,6 +47,35 @@ slow.invoke = pickle_debug.cached(slow.invoke) # one instance
|
|
|
47
47
|
Slow.invoke = pickle_debug.cached(Slow.invoke) # all instances
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
The decorator also works inside a class body. For a classmethod, put `@cached` below `@classmethod`:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
class Slow:
|
|
54
|
+
@pickle_debug.cached
|
|
55
|
+
def invoke(self, x):
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
@pickle_debug.cached
|
|
60
|
+
def build(cls, x):
|
|
61
|
+
...
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
A wrapper may be needed to cache some functions, e.g. a method returning a generator:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
def something(x,y,z)->Generator:
|
|
68
|
+
|
|
69
|
+
@pickle_debug.cached
|
|
70
|
+
def cache_something(x,y,z)->list:
|
|
71
|
+
return list(something(x,y,z))
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
When a cached function is called as a method, `self` (or `cls`) is keyed by its class's name
|
|
75
|
+
(`module.QualifiedName`), not its current value. All instances of a class share cache entries, and the
|
|
76
|
+
instance does not need to be picklable. Subclasses get their own entries. Static methods are keyed like
|
|
77
|
+
plain functions.
|
|
78
|
+
|
|
50
79
|
## API
|
|
51
80
|
|
|
52
81
|
### `enable(directory)`
|
|
@@ -58,7 +87,8 @@ Decorator. Returns a wrapper (using `functools.wraps`) that:
|
|
|
58
87
|
|
|
59
88
|
1. calls `func` directly if caching is not enabled;
|
|
60
89
|
2. otherwise builds a key from `func.__module__`, `func.__qualname__`, the positional arguments and
|
|
61
|
-
the sorted keyword arguments, and hashes it with SHA-256
|
|
90
|
+
the sorted keyword arguments, and hashes it with SHA-256. If `func` is called as a method, the
|
|
91
|
+
first argument (`self` or `cls`) is replaced by its class's name (see [Methods](#methods));
|
|
62
92
|
3. returns the pickled result from `<directory>/<hash>.pickle` if present;
|
|
63
93
|
4. otherwise calls `func`, writes the result to the cache, and returns it.
|
|
64
94
|
|
|
@@ -89,13 +119,15 @@ wrong place. It does nothing if caching is not enabled or the directory does not
|
|
|
89
119
|
[Unpicklable attributes](#unpicklable-attributes)). The arguments are pickled to build the key, and the
|
|
90
120
|
result is pickled to store it. Because dropped attributes are not part of the key, two arguments that
|
|
91
121
|
differ only in unpicklable attributes share a cache entry.
|
|
122
|
+
- **Wrappers may be required** for methods that return generators.
|
|
92
123
|
- **The key is the pickled arguments.** Equal arguments that pickle differently (for example sets with a
|
|
93
124
|
different iteration order) may miss the cache. Objects whose pickle changes between calls never hit it.
|
|
94
125
|
- **The key does not include the function's code or any files it reads.** If you change the function or
|
|
95
126
|
its input data, call `reset()` or use a new cache directory, or you will get stale results.
|
|
96
|
-
- **
|
|
97
|
-
so all instances share entries.
|
|
98
|
-
|
|
127
|
+
- **Instance state is not part of the key.** Methods are keyed by the class of `self` or `cls`, not by its
|
|
128
|
+
value, so all instances of a class share entries. If a method's result depends on instance attributes,
|
|
129
|
+
instances with different state will get each other's cached results. Pass that state as an argument
|
|
130
|
+
instead, or call `reset()` between runs.
|
|
99
131
|
- This is a debugging aid. Do not use it as a production cache. Cached files are loaded with `pickle`,
|
|
100
132
|
so only use a directory you trust.
|
|
101
133
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pickle_debug
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0
|
|
4
4
|
Summary: Store expensive objects from debugging
|
|
5
5
|
Author: Gerard
|
|
6
6
|
Author-email: gweatherby@uchc.edu
|
|
@@ -59,6 +59,35 @@ slow.invoke = pickle_debug.cached(slow.invoke) # one instance
|
|
|
59
59
|
Slow.invoke = pickle_debug.cached(Slow.invoke) # all instances
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
The decorator also works inside a class body. For a classmethod, put `@cached` below `@classmethod`:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
class Slow:
|
|
66
|
+
@pickle_debug.cached
|
|
67
|
+
def invoke(self, x):
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
@pickle_debug.cached
|
|
72
|
+
def build(cls, x):
|
|
73
|
+
...
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
A wrapper may be needed to cache some functions, e.g. a method returning a generator:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
def something(x,y,z)->Generator:
|
|
80
|
+
|
|
81
|
+
@pickle_debug.cached
|
|
82
|
+
def cache_something(x,y,z)->list:
|
|
83
|
+
return list(something(x,y,z))
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
When a cached function is called as a method, `self` (or `cls`) is keyed by its class's name
|
|
87
|
+
(`module.QualifiedName`), not its current value. All instances of a class share cache entries, and the
|
|
88
|
+
instance does not need to be picklable. Subclasses get their own entries. Static methods are keyed like
|
|
89
|
+
plain functions.
|
|
90
|
+
|
|
62
91
|
## API
|
|
63
92
|
|
|
64
93
|
### `enable(directory)`
|
|
@@ -70,7 +99,8 @@ Decorator. Returns a wrapper (using `functools.wraps`) that:
|
|
|
70
99
|
|
|
71
100
|
1. calls `func` directly if caching is not enabled;
|
|
72
101
|
2. otherwise builds a key from `func.__module__`, `func.__qualname__`, the positional arguments and
|
|
73
|
-
the sorted keyword arguments, and hashes it with SHA-256
|
|
102
|
+
the sorted keyword arguments, and hashes it with SHA-256. If `func` is called as a method, the
|
|
103
|
+
first argument (`self` or `cls`) is replaced by its class's name (see [Methods](#methods));
|
|
74
104
|
3. returns the pickled result from `<directory>/<hash>.pickle` if present;
|
|
75
105
|
4. otherwise calls `func`, writes the result to the cache, and returns it.
|
|
76
106
|
|
|
@@ -101,13 +131,15 @@ wrong place. It does nothing if caching is not enabled or the directory does not
|
|
|
101
131
|
[Unpicklable attributes](#unpicklable-attributes)). The arguments are pickled to build the key, and the
|
|
102
132
|
result is pickled to store it. Because dropped attributes are not part of the key, two arguments that
|
|
103
133
|
differ only in unpicklable attributes share a cache entry.
|
|
134
|
+
- **Wrappers may be required** for methods that return generators.
|
|
104
135
|
- **The key is the pickled arguments.** Equal arguments that pickle differently (for example sets with a
|
|
105
136
|
different iteration order) may miss the cache. Objects whose pickle changes between calls never hit it.
|
|
106
137
|
- **The key does not include the function's code or any files it reads.** If you change the function or
|
|
107
138
|
its input data, call `reset()` or use a new cache directory, or you will get stale results.
|
|
108
|
-
- **
|
|
109
|
-
so all instances share entries.
|
|
110
|
-
|
|
139
|
+
- **Instance state is not part of the key.** Methods are keyed by the class of `self` or `cls`, not by its
|
|
140
|
+
value, so all instances of a class share entries. If a method's result depends on instance attributes,
|
|
141
|
+
instances with different state will get each other's cached results. Pass that state as an argument
|
|
142
|
+
instead, or call `reset()` between runs.
|
|
111
143
|
- This is a debugging aid. Do not use it as a production cache. Cached files are loaded with `pickle`,
|
|
112
144
|
so only use a directory you trust.
|
|
113
145
|
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import pathlib
|
|
2
|
-
import tempfile
|
|
3
|
-
import threading
|
|
4
|
-
|
|
5
|
-
from pickle_debug import cached, enable
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Holder:
|
|
9
|
-
def __init__(self, value):
|
|
10
|
-
self.value = value
|
|
11
|
-
self.lock = threading.Lock()
|
|
12
|
-
self.inner = Inner()
|
|
13
|
-
self.me = self
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class Inner:
|
|
17
|
-
def __init__(self):
|
|
18
|
-
self.ok = 'inner'
|
|
19
|
-
self.callback = lambda: None
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class Slotted:
|
|
23
|
-
__slots__ = ('a', 'lock')
|
|
24
|
-
|
|
25
|
-
def __init__(self):
|
|
26
|
-
self.a = 1
|
|
27
|
-
self.lock = threading.Lock()
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
calls = []
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
@cached
|
|
34
|
-
def make(x):
|
|
35
|
-
calls.append(x)
|
|
36
|
-
return Holder(x), Slotted()
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
enable(pathlib.Path(tempfile.mkdtemp()) / 'cache')
|
|
40
|
-
make(5)
|
|
41
|
-
h, s = make(5)
|
|
42
|
-
assert calls == [5], calls
|
|
43
|
-
assert h.value == 5 and not hasattr(h, 'lock') and h.me is h
|
|
44
|
-
assert h.inner.ok == 'inner' and not hasattr(h.inner, 'callback')
|
|
45
|
-
assert s.a == 1 and not hasattr(s, 'lock')
|
|
46
|
-
print('ok')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|