k3cacheable 0.1.0__tar.gz → 0.1.2__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 张炎泼
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,126 @@
1
+ Metadata-Version: 2.4
2
+ Name: k3cacheable
3
+ Version: 0.1.2
4
+ Summary: Cache data which access frequently
5
+ Author-email: Zhang Yanpo <drdr.xp@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/pykit3/k3cacheable
8
+ Project-URL: Documentation, https://k3cacheable.readthedocs.io
9
+ Keywords: cache,cacheable,memoize,pykit3
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Topic :: Software Development :: Libraries
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: msgpack
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=7.0; extra == "dev"
25
+ Requires-Dist: ruff; extra == "dev"
26
+ Requires-Dist: coverage; extra == "dev"
27
+ Provides-Extra: publish
28
+ Requires-Dist: build; extra == "publish"
29
+ Requires-Dist: twine; extra == "publish"
30
+ Requires-Dist: pk3; extra == "publish"
31
+ Provides-Extra: docs
32
+ Requires-Dist: mkdocs>=1.5; extra == "docs"
33
+ Requires-Dist: mkdocs-material>=9.0; extra == "docs"
34
+ Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
35
+ Dynamic: license-file
36
+
37
+ # k3cacheable
38
+
39
+ [![Action-CI](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml/badge.svg)](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml)
40
+ [![Documentation Status](https://readthedocs.org/projects/k3cacheable/badge/?version=stable)](https://k3cacheable.readthedocs.io/en/stable/?badge=stable)
41
+ [![Package](https://img.shields.io/pypi/pyversions/k3cacheable)](https://pypi.org/project/k3cacheable)
42
+
43
+ Cache data which access frequently.
44
+
45
+ k3cacheable is a component of [pykit3] project: a python3 toolkit set.
46
+
47
+
48
+ Cache data which access frequently.
49
+
50
+
51
+
52
+
53
+ # Install
54
+
55
+ ```
56
+ pip install k3cacheable
57
+ ```
58
+
59
+ # Synopsis
60
+
61
+ ```python
62
+
63
+ import k3cacheable
64
+ import time
65
+
66
+ # create a `LRU`, capacity:10 timeout:60
67
+ c = k3cacheable.LRU(10, 60)
68
+
69
+ # set value like the `dict`
70
+ c['key'] = 'val'
71
+
72
+ # get value like the `dict`
73
+ # if item timeout, delete it and raise `KeyError`
74
+ # if item not exist, raise `KeyError`
75
+ try:
76
+ val = c['key']
77
+ except KeyError:
78
+ print('key error')
79
+
80
+ cache_data = {
81
+ 'key1': 'val_1',
82
+ 'key2': 'val_2',
83
+ }
84
+
85
+ # define the function with a decorator
86
+ @k3cacheable.cache('cache_name', capacity=100, timeout=60,
87
+ is_deepcopy=False, mutex_update=False)
88
+ def get_data(param):
89
+ return cache_data.get(param, '')
90
+
91
+ # call `get_data`, if item has not been cached, cache the return value
92
+ data = get_data('key1')
93
+
94
+ # call `get_data` use the same param, data will be got from cache
95
+ time.sleep(1)
96
+ data = get_data('key1')
97
+
98
+ # if item timeout, when call `get_data`, cache again
99
+ time.sleep(1)
100
+ data = get_data('key1')
101
+
102
+ # define a method with a decorator
103
+ class MethodCache(object):
104
+
105
+ @k3cacheable.cache('method_cache_name', capacity=100, timeout=60,
106
+ is_deepcopy=False, mutex_update=False)
107
+ def get_data(self, param):
108
+ return cache_data.get(param, '')
109
+
110
+ mm = MethodCache()
111
+ data = mm.get_data('key2')
112
+
113
+ ```
114
+
115
+ # Author
116
+
117
+ Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>
118
+
119
+ # Copyright and License
120
+
121
+ The MIT License (MIT)
122
+
123
+ Copyright (c) 2015 Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>
124
+
125
+
126
+ [pykit3]: https://github.com/pykit3
@@ -1,49 +1,90 @@
1
- import k3cacheable
2
- import time
3
-
4
- # create a `LRU`, capacity:10 timeout:60
5
- c = k3cacheable.LRU(10, 60)
6
-
7
- # set value like the `dict`
8
- c['key'] = 'val'
9
-
10
- # get value like the `dict`
11
- # if item timeout, delete it and raise `KeyError`
12
- # if item not exist, raise `KeyError`
13
- try:
14
- val = c['key']
15
- except KeyError:
16
- print('key error')
17
-
18
- cache_data = {
19
- 'key1': 'val_1',
20
- 'key2': 'val_2',
21
- }
22
-
23
- # define the function with a decorator
24
- @k3cacheable.cache('cache_name', capacity=100, timeout=60,
25
- is_deepcopy=False, mutex_update=False)
26
- def get_data(param):
27
- return cache_data.get(param, '')
28
-
29
- # call `get_data`, if item has not been cached, cache the return value
30
- data = get_data('key1')
31
-
32
- # call `get_data` use the same param, data will be got from cache
33
- time.sleep(1)
34
- data = get_data('key1')
35
-
36
- # if item timeout, when call `get_data`, cache again
37
- time.sleep(1)
38
- data = get_data('key1')
39
-
40
- # define a method with a decorator
41
- class MethodCache(object):
42
-
43
- @k3cacheable.cache('method_cache_name', capacity=100, timeout=60,
44
- is_deepcopy=False, mutex_update=False)
45
- def get_data(self, param):
46
- return cache_data.get(param, '')
47
-
48
- mm = MethodCache()
49
- data = mm.get_data('key2')
1
+ # k3cacheable
2
+
3
+ [![Action-CI](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml/badge.svg)](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml)
4
+ [![Documentation Status](https://readthedocs.org/projects/k3cacheable/badge/?version=stable)](https://k3cacheable.readthedocs.io/en/stable/?badge=stable)
5
+ [![Package](https://img.shields.io/pypi/pyversions/k3cacheable)](https://pypi.org/project/k3cacheable)
6
+
7
+ Cache data which access frequently.
8
+
9
+ k3cacheable is a component of [pykit3] project: a python3 toolkit set.
10
+
11
+
12
+ Cache data which access frequently.
13
+
14
+
15
+
16
+
17
+ # Install
18
+
19
+ ```
20
+ pip install k3cacheable
21
+ ```
22
+
23
+ # Synopsis
24
+
25
+ ```python
26
+
27
+ import k3cacheable
28
+ import time
29
+
30
+ # create a `LRU`, capacity:10 timeout:60
31
+ c = k3cacheable.LRU(10, 60)
32
+
33
+ # set value like the `dict`
34
+ c['key'] = 'val'
35
+
36
+ # get value like the `dict`
37
+ # if item timeout, delete it and raise `KeyError`
38
+ # if item not exist, raise `KeyError`
39
+ try:
40
+ val = c['key']
41
+ except KeyError:
42
+ print('key error')
43
+
44
+ cache_data = {
45
+ 'key1': 'val_1',
46
+ 'key2': 'val_2',
47
+ }
48
+
49
+ # define the function with a decorator
50
+ @k3cacheable.cache('cache_name', capacity=100, timeout=60,
51
+ is_deepcopy=False, mutex_update=False)
52
+ def get_data(param):
53
+ return cache_data.get(param, '')
54
+
55
+ # call `get_data`, if item has not been cached, cache the return value
56
+ data = get_data('key1')
57
+
58
+ # call `get_data` use the same param, data will be got from cache
59
+ time.sleep(1)
60
+ data = get_data('key1')
61
+
62
+ # if item timeout, when call `get_data`, cache again
63
+ time.sleep(1)
64
+ data = get_data('key1')
65
+
66
+ # define a method with a decorator
67
+ class MethodCache(object):
68
+
69
+ @k3cacheable.cache('method_cache_name', capacity=100, timeout=60,
70
+ is_deepcopy=False, mutex_update=False)
71
+ def get_data(self, param):
72
+ return cache_data.get(param, '')
73
+
74
+ mm = MethodCache()
75
+ data = mm.get_data('key2')
76
+
77
+ ```
78
+
79
+ # Author
80
+
81
+ Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>
82
+
83
+ # Copyright and License
84
+
85
+ The MIT License (MIT)
86
+
87
+ Copyright (c) 2015 Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>
88
+
89
+
90
+ [pykit3]: https://github.com/pykit3
@@ -6,8 +6,9 @@ Cache data which access frequently.
6
6
  # from .proc import CalledProcessError
7
7
  # from .proc import ProcError
8
8
 
9
- __version__ = "0.1.0"
10
- __name__ = "k3cacheable"
9
+ from importlib.metadata import version
10
+
11
+ __version__ = version("k3cacheable")
11
12
 
12
13
  from .cacheable import (
13
14
  LRU,
@@ -16,7 +17,7 @@ from .cacheable import (
16
17
  )
17
18
 
18
19
  __all__ = [
19
- 'LRU',
20
- 'Cacheable',
21
- 'cache',
20
+ "LRU",
21
+ "Cacheable",
22
+ "cache",
22
23
  ]
@@ -23,7 +23,7 @@ class LRU(object):
23
23
 
24
24
  If size of `LRU` is greater than `capacity` * 1.5,
25
25
  clean items from head until size is equal to `capacity`.
26
-
26
+
27
27
  .. highlight:: python
28
28
  .. code-block:: python
29
29
 
@@ -51,6 +51,7 @@ class LRU(object):
51
51
  print('key not in lru')
52
52
  ...
53
53
  """
54
+
54
55
  def __init__(self, capacity, timeout=60):
55
56
  """
56
57
  Least Recently Used Cache.
@@ -64,39 +65,33 @@ class LRU(object):
64
65
  self.timeout = timeout
65
66
  self.size = 0
66
67
  self.items = {}
67
- self.head = {'next': None, 'pre': None}
68
+ self.head = {"next": None, "pre": None}
68
69
  self.tail = self.head
69
70
 
70
71
  def __getitem__(self, key):
71
-
72
72
  with self.lock:
73
73
  now = int(time.time())
74
74
  item = self.items[key]
75
75
 
76
- if now > item['tm'] + self.timeout:
76
+ if now > item["tm"] + self.timeout:
77
77
  self._del_item(item)
78
- raise KeyError('{k} is timeout'.format(k=key))
78
+ raise KeyError("{k} is timeout".format(k=key))
79
79
 
80
80
  self._move_to_tail(item)
81
81
 
82
- return item['val']
82
+ return item["val"]
83
83
 
84
84
  def __setitem__(self, key, val):
85
-
86
85
  with self.lock:
87
86
  if key in self.items:
88
87
  item = self.items[key]
89
- item['val'] = val
90
- item['tm'] = int(time.time())
88
+ item["val"] = val
89
+ item["tm"] = int(time.time())
91
90
 
92
91
  self._move_to_tail(item)
93
92
 
94
93
  else:
95
- self.items[key] = {'key': key,
96
- 'val': val,
97
- 'pre': None,
98
- 'next': None,
99
- 'tm': int(time.time())}
94
+ self.items[key] = {"key": key, "val": val, "pre": None, "next": None, "tm": int(time.time())}
100
95
 
101
96
  self._move_to_tail(self.items[key])
102
97
 
@@ -106,40 +101,34 @@ class LRU(object):
106
101
  self._cleanup()
107
102
 
108
103
  def _remove_item(self, item):
109
-
110
- item['pre']['next'] = item['next']
111
- if item['next'] is not None:
112
- item['next']['pre'] = item['pre']
104
+ item["pre"]["next"] = item["next"]
105
+ if item["next"] is not None:
106
+ item["next"]["pre"] = item["pre"]
113
107
  else:
114
- self.tail = item['pre']
108
+ self.tail = item["pre"]
115
109
 
116
110
  def _move_to_tail(self, item):
117
-
118
- if item['pre'] is not None:
111
+ if item["pre"] is not None:
119
112
  self._remove_item(item)
120
113
 
121
- self.tail['next'] = item
122
- item['pre'] = self.tail
123
- item['next'] = None
114
+ self.tail["next"] = item
115
+ item["pre"] = self.tail
116
+ item["next"] = None
124
117
  self.tail = item
125
118
 
126
119
  def _del_item(self, item):
127
-
128
- del self.items[item['key']]
120
+ del self.items[item["key"]]
129
121
  self._remove_item(item)
130
122
  self.size -= 1
131
123
 
132
124
  def _cleanup(self):
133
-
134
125
  while self.size > self.capacity:
135
- item = self.head['next']
126
+ item = self.head["next"]
136
127
  self._del_item(item)
137
128
 
138
129
 
139
130
  class Cacheable(object):
140
-
141
- def __init__(self, capacity=1024 * 4, timeout=60,
142
- is_deepcopy=True, is_pack=False, mutex_update=False):
131
+ def __init__(self, capacity=1024 * 4, timeout=60, is_deepcopy=True, is_pack=False, mutex_update=False):
143
132
  """
144
133
  Create a `LRU` object, all items will be cached in it.
145
134
  :param capacity: for create `LRU` object, default is 1024 * 4
@@ -166,16 +155,13 @@ class Cacheable(object):
166
155
  self.mutex_update = mutex_update
167
156
 
168
157
  def _arg_str(self, args, argkv):
169
-
170
158
  argkv = [(k, v) for k, v in list(argkv.items())]
171
159
  argkv.sort()
172
160
 
173
161
  return str([args, argkv])
174
162
 
175
163
  def _cache_wrapper(self, fun):
176
-
177
164
  def func_wrapper(*args, **argkv):
178
-
179
165
  val = None
180
166
  generate_key = self._arg_str(args, argkv)
181
167
 
@@ -211,8 +197,7 @@ class Cacheable(object):
211
197
  caches = {}
212
198
 
213
199
 
214
- def cache(name, capacity=1024 * 4, timeout=60,
215
- is_deepcopy=True, is_pack=False, mutex_update=False):
200
+ def cache(name, capacity=1024 * 4, timeout=60, is_deepcopy=True, is_pack=False, mutex_update=False):
216
201
  """
217
202
  If not exist, create a `cacheable.Cacheable` and save it, else use exist one.
218
203
  :param name: for distinguishing different `cacheable.Cacheable`
@@ -244,8 +229,7 @@ def cache(name, capacity=1024 * 4, timeout=60,
244
229
  """
245
230
  c = caches.get(name)
246
231
  if c is None:
247
- c = Cacheable(capacity=capacity, timeout=timeout,
248
- is_deepcopy=is_deepcopy, mutex_update=mutex_update)
232
+ c = Cacheable(capacity=capacity, timeout=timeout, is_deepcopy=is_deepcopy, mutex_update=mutex_update)
249
233
  caches[name] = c
250
234
 
251
235
  return c._cache_wrapper
@@ -0,0 +1,126 @@
1
+ Metadata-Version: 2.4
2
+ Name: k3cacheable
3
+ Version: 0.1.2
4
+ Summary: Cache data which access frequently
5
+ Author-email: Zhang Yanpo <drdr.xp@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/pykit3/k3cacheable
8
+ Project-URL: Documentation, https://k3cacheable.readthedocs.io
9
+ Keywords: cache,cacheable,memoize,pykit3
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Topic :: Software Development :: Libraries
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: msgpack
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=7.0; extra == "dev"
25
+ Requires-Dist: ruff; extra == "dev"
26
+ Requires-Dist: coverage; extra == "dev"
27
+ Provides-Extra: publish
28
+ Requires-Dist: build; extra == "publish"
29
+ Requires-Dist: twine; extra == "publish"
30
+ Requires-Dist: pk3; extra == "publish"
31
+ Provides-Extra: docs
32
+ Requires-Dist: mkdocs>=1.5; extra == "docs"
33
+ Requires-Dist: mkdocs-material>=9.0; extra == "docs"
34
+ Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
35
+ Dynamic: license-file
36
+
37
+ # k3cacheable
38
+
39
+ [![Action-CI](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml/badge.svg)](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml)
40
+ [![Documentation Status](https://readthedocs.org/projects/k3cacheable/badge/?version=stable)](https://k3cacheable.readthedocs.io/en/stable/?badge=stable)
41
+ [![Package](https://img.shields.io/pypi/pyversions/k3cacheable)](https://pypi.org/project/k3cacheable)
42
+
43
+ Cache data which access frequently.
44
+
45
+ k3cacheable is a component of [pykit3] project: a python3 toolkit set.
46
+
47
+
48
+ Cache data which access frequently.
49
+
50
+
51
+
52
+
53
+ # Install
54
+
55
+ ```
56
+ pip install k3cacheable
57
+ ```
58
+
59
+ # Synopsis
60
+
61
+ ```python
62
+
63
+ import k3cacheable
64
+ import time
65
+
66
+ # create a `LRU`, capacity:10 timeout:60
67
+ c = k3cacheable.LRU(10, 60)
68
+
69
+ # set value like the `dict`
70
+ c['key'] = 'val'
71
+
72
+ # get value like the `dict`
73
+ # if item timeout, delete it and raise `KeyError`
74
+ # if item not exist, raise `KeyError`
75
+ try:
76
+ val = c['key']
77
+ except KeyError:
78
+ print('key error')
79
+
80
+ cache_data = {
81
+ 'key1': 'val_1',
82
+ 'key2': 'val_2',
83
+ }
84
+
85
+ # define the function with a decorator
86
+ @k3cacheable.cache('cache_name', capacity=100, timeout=60,
87
+ is_deepcopy=False, mutex_update=False)
88
+ def get_data(param):
89
+ return cache_data.get(param, '')
90
+
91
+ # call `get_data`, if item has not been cached, cache the return value
92
+ data = get_data('key1')
93
+
94
+ # call `get_data` use the same param, data will be got from cache
95
+ time.sleep(1)
96
+ data = get_data('key1')
97
+
98
+ # if item timeout, when call `get_data`, cache again
99
+ time.sleep(1)
100
+ data = get_data('key1')
101
+
102
+ # define a method with a decorator
103
+ class MethodCache(object):
104
+
105
+ @k3cacheable.cache('method_cache_name', capacity=100, timeout=60,
106
+ is_deepcopy=False, mutex_update=False)
107
+ def get_data(self, param):
108
+ return cache_data.get(param, '')
109
+
110
+ mm = MethodCache()
111
+ data = mm.get_data('key2')
112
+
113
+ ```
114
+
115
+ # Author
116
+
117
+ Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>
118
+
119
+ # Copyright and License
120
+
121
+ The MIT License (MIT)
122
+
123
+ Copyright (c) 2015 Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>
124
+
125
+
126
+ [pykit3]: https://github.com/pykit3
@@ -0,0 +1,16 @@
1
+ LICENSE
2
+ README.md
3
+ __init__.py
4
+ cacheable.py
5
+ pyproject.toml
6
+ synopsis.py
7
+ ./__init__.py
8
+ ./cacheable.py
9
+ ./synopsis.py
10
+ k3cacheable.egg-info/PKG-INFO
11
+ k3cacheable.egg-info/SOURCES.txt
12
+ k3cacheable.egg-info/dependency_links.txt
13
+ k3cacheable.egg-info/requires.txt
14
+ k3cacheable.egg-info/top_level.txt
15
+ test/test_doctest.py
16
+ test/test_k3cacheable.py
@@ -0,0 +1,16 @@
1
+ msgpack
2
+
3
+ [dev]
4
+ pytest>=7.0
5
+ ruff
6
+ coverage
7
+
8
+ [docs]
9
+ mkdocs>=1.5
10
+ mkdocs-material>=9.0
11
+ mkdocstrings[python]>=0.24
12
+
13
+ [publish]
14
+ build
15
+ twine
16
+ pk3
@@ -0,0 +1,59 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "k3cacheable"
7
+ version = "0.1.2"
8
+ description = "Cache data which access frequently"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.9"
12
+ authors = [
13
+ { name = "Zhang Yanpo", email = "drdr.xp@gmail.com" }
14
+ ]
15
+ keywords = ["cache", "cacheable", "memoize", "pykit3"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "Topic :: Software Development :: Libraries",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ ]
27
+ dependencies = [
28
+ "msgpack",
29
+ ]
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/pykit3/k3cacheable"
33
+ Documentation = "https://k3cacheable.readthedocs.io"
34
+
35
+ [project.optional-dependencies]
36
+ dev = [
37
+ "pytest>=7.0",
38
+ "ruff",
39
+ "coverage",
40
+ ]
41
+ publish = [
42
+ "build",
43
+ "twine",
44
+ "pk3",
45
+ ]
46
+ docs = [
47
+ "mkdocs>=1.5",
48
+ "mkdocs-material>=9.0",
49
+ "mkdocstrings[python]>=0.24",
50
+ ]
51
+
52
+ [tool.setuptools]
53
+ packages = ["k3cacheable"]
54
+
55
+ [tool.setuptools.package-dir]
56
+ k3cacheable = "."
57
+
58
+ [tool.ruff]
59
+ line-length = 120
@@ -0,0 +1,50 @@
1
+ import k3cacheable
2
+ import time
3
+
4
+ # create a `LRU`, capacity:10 timeout:60
5
+ c = k3cacheable.LRU(10, 60)
6
+
7
+ # set value like the `dict`
8
+ c["key"] = "val"
9
+
10
+ # get value like the `dict`
11
+ # if item timeout, delete it and raise `KeyError`
12
+ # if item not exist, raise `KeyError`
13
+ try:
14
+ val = c["key"]
15
+ except KeyError:
16
+ print("key error")
17
+
18
+ cache_data = {
19
+ "key1": "val_1",
20
+ "key2": "val_2",
21
+ }
22
+
23
+
24
+ # define the function with a decorator
25
+ @k3cacheable.cache("cache_name", capacity=100, timeout=60, is_deepcopy=False, mutex_update=False)
26
+ def get_data(param):
27
+ return cache_data.get(param, "")
28
+
29
+
30
+ # call `get_data`, if item has not been cached, cache the return value
31
+ data = get_data("key1")
32
+
33
+ # call `get_data` use the same param, data will be got from cache
34
+ time.sleep(1)
35
+ data = get_data("key1")
36
+
37
+ # if item timeout, when call `get_data`, cache again
38
+ time.sleep(1)
39
+ data = get_data("key1")
40
+
41
+
42
+ # define a method with a decorator
43
+ class MethodCache(object):
44
+ @k3cacheable.cache("method_cache_name", capacity=100, timeout=60, is_deepcopy=False, mutex_update=False)
45
+ def get_data(self, param):
46
+ return cache_data.get(param, "")
47
+
48
+
49
+ mm = MethodCache()
50
+ data = mm.get_data("key2")
@@ -0,0 +1,8 @@
1
+ import doctest
2
+
3
+ import k3cacheable
4
+
5
+
6
+ def load_tests(loader, tests, ignore):
7
+ tests.addTests(doctest.DocTestSuite(k3cacheable))
8
+ return tests
@@ -0,0 +1,231 @@
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ import _thread
5
+ import time
6
+ import unittest
7
+
8
+ import k3cacheable
9
+
10
+
11
+ class TestLRU(unittest.TestCase):
12
+ def _assert_lru_list(self, lru):
13
+ size = lru.size
14
+ item_head = lru.head
15
+ item_tail = lru.tail
16
+ for i in range(size):
17
+ item_head = item_head["next"]
18
+ item_tail = item_tail["pre"]
19
+
20
+ self.assertIs(item_head, lru.tail)
21
+ self.assertIs(item_tail, lru.head)
22
+
23
+ def _assert_lru_items_order(self, lru, order_keys):
24
+ item = lru.head["next"]
25
+ lru_keys = []
26
+ while item is not None:
27
+ lru_keys.append(item["key"])
28
+ item = item["next"]
29
+
30
+ self.assertEqual(order_keys, lru_keys)
31
+
32
+ def test_lru_timeout(self):
33
+ cases = (
34
+ ("k1", "v1", 3, True),
35
+ ("k2", "v2", 1, False),
36
+ )
37
+
38
+ lru = k3cacheable.LRU(10, 2)
39
+ for key, val, sleep_time, is_timeout in cases:
40
+ lru[key] = val
41
+ time.sleep(sleep_time)
42
+
43
+ try:
44
+ lru[key]
45
+ self.assertFalse(is_timeout)
46
+
47
+ except KeyError:
48
+ self._assert_lru_list(lru)
49
+ self.assertTrue(is_timeout)
50
+
51
+ def test_lru_getitem(self):
52
+ capacity = 4
53
+ cases = (
54
+ (3, [0, 1, 2], []),
55
+ (4, [0, 1, 2, 3], []),
56
+ (5, [0, 1, 2, 3, 4], []),
57
+ (6, [0, 1, 2, 3, 4, 5], []),
58
+ (7, [3, 4, 5, 6], [0, 1, 2]),
59
+ )
60
+
61
+ for insert_count, exist_items, cleanup_items in cases:
62
+ lru = k3cacheable.LRU(capacity, 10)
63
+ for i in range(insert_count):
64
+ lru[i] = "val%d" % (i)
65
+
66
+ for i in range(insert_count):
67
+ try:
68
+ val = lru[i]
69
+ self.assertEqual(val, "val%d" % (i))
70
+ self.assertEqual(lru.tail["key"], i)
71
+ self.assertIn(i, exist_items)
72
+
73
+ except KeyError:
74
+ self.assertIn(i, cleanup_items)
75
+
76
+ def test_lru_setitem(self):
77
+ capacity = 4
78
+ cases = (
79
+ (3, [0, 1, 2]),
80
+ (4, [0, 1, 2, 3]),
81
+ (5, [0, 1, 2, 3, 4]),
82
+ (6, [0, 1, 2, 3, 4, 5]),
83
+ # size of lru > capacity*1.5
84
+ # clean items from head, until size=capacity
85
+ (7, [3, 4, 5, 6]),
86
+ )
87
+
88
+ for insert_count, expect_order_keys in cases:
89
+ lru = k3cacheable.LRU(capacity, 10)
90
+ for i in range(insert_count):
91
+ lru[i] = "val"
92
+ self._assert_lru_list(lru)
93
+
94
+ self._assert_lru_items_order(lru, expect_order_keys)
95
+
96
+ def test_lru_capacity(self):
97
+ cases = (
98
+ (0, ((0, 0), (1, 0))),
99
+ (1, ((1, 1), (2, 1))),
100
+ (10, ((9, 9), (10, 10), (13, 13), (15, 15), (16, 10))),
101
+ )
102
+
103
+ for capacity, case in cases:
104
+ for insert_count, expect_size in case:
105
+ lru = k3cacheable.LRU(capacity, 60)
106
+ for i in range(insert_count):
107
+ lru[i] = "val"
108
+
109
+ self.assertEqual(lru.size, expect_size)
110
+
111
+
112
+ class TestCacheable(unittest.TestCase):
113
+ @k3cacheable.cache("method_cache_data", capacity=10, timeout=4, is_deepcopy=False)
114
+ def _method_cache_data(self, key):
115
+ data = need_cache_data.get(key, {})
116
+ data["tm"] = time.time()
117
+ return data
118
+
119
+ def test_get_items_from_cache(self):
120
+ cache_items = {}
121
+ for key in need_cache_data.keys():
122
+ cache_items[key] = get_cache_data(key)
123
+
124
+ time.sleep(0.1)
125
+ for key in need_cache_data.keys():
126
+ self.assertEqual(get_cache_data(key), cache_items[key])
127
+
128
+ def test_get_items_from_cache_use_method(self):
129
+ cache_items = {}
130
+ for key in need_cache_data.keys():
131
+ cache_items[key] = self._method_cache_data(key)
132
+
133
+ time.sleep(0.1)
134
+ for key in need_cache_data.keys():
135
+ self.assertEqual(self._method_cache_data(key), cache_items[key])
136
+
137
+ def test_cache_item_timeout_and_cache_again(self):
138
+ cases = (
139
+ (2, False),
140
+ (4, True),
141
+ )
142
+
143
+ tm = get_cache_data("key")["tm"]
144
+ for sleep_time, is_timeout in cases:
145
+ time.sleep(sleep_time)
146
+ if is_timeout:
147
+ self.assertNotEqual(tm, get_cache_data("key")["tm"])
148
+ else:
149
+ self.assertEqual(tm, get_cache_data("key")["tm"])
150
+
151
+ def test_get_deepcopy_item_from_cache(self):
152
+ self.assertIsNot(get_deepcopy_of_cache_data("key1"), get_deepcopy_of_cache_data("key1"))
153
+
154
+ def test_get_concurrent_update_cache_data(self):
155
+ result = {}
156
+
157
+ def _store_result(key):
158
+ result[key] = get_concurrent_update_cache_data()
159
+
160
+ _thread.start_new_thread(_store_result, ("key1",))
161
+ time.sleep(1)
162
+ _thread.start_new_thread(_store_result, ("key2",))
163
+
164
+ while True:
165
+ if "key2" in result:
166
+ break
167
+ time.sleep(0.1)
168
+
169
+ self.assertIsNot(result["key1"], result["key2"])
170
+
171
+ def test_get_mutext_update_cache_data(self):
172
+ result = {}
173
+
174
+ def _store_result(key):
175
+ result[key] = get_mutex_update_cache_data()
176
+
177
+ _thread.start_new_thread(_store_result, ("key1",))
178
+ time.sleep(1)
179
+ _thread.start_new_thread(_store_result, ("key2",))
180
+
181
+ while True:
182
+ if "key2" in result:
183
+ break
184
+ time.sleep(0.1)
185
+
186
+ self.assertIs(result["key1"], result["key2"])
187
+
188
+ def test_generate_lru_key(self):
189
+ cases = (
190
+ ((), {}, "[(), []]"),
191
+ ((1), {1: "val_1"}, "[1, [(1, 'val_1')]]"),
192
+ ((1), {"a": "val_a"}, "[1, [('a', 'val_a')]]"),
193
+ (("c"), {"b": "val_b"}, "['c', [('b', 'val_b')]]"),
194
+ ((1, "c"), {"a": "val_a", "b": "val_b"}, "[(1, 'c'), [('a', 'val_a'), ('b', 'val_b')]]"),
195
+ (("c", 1), {"b": "val_b", "a": "val_a"}, "[('c', 1), [('a', 'val_a'), ('b', 'val_b')]]"),
196
+ )
197
+
198
+ for args, argkv, expect_str in cases:
199
+ self.assertEqual(k3cacheable.Cacheable()._arg_str(args, argkv), expect_str)
200
+
201
+
202
+ @k3cacheable.cache("deepcopy_of_cache_data", capacity=100, timeout=60, is_deepcopy=True)
203
+ def get_deepcopy_of_cache_data(key):
204
+ return need_cache_data.get(key, {})
205
+
206
+
207
+ @k3cacheable.cache("cache_data", capacity=100, timeout=4, is_deepcopy=False)
208
+ def get_cache_data(key):
209
+ cache_data = need_cache_data.get(key, {})
210
+ cache_data["tm"] = time.time()
211
+ return cache_data
212
+
213
+
214
+ @k3cacheable.cache("concurrent_update_cache_data", capacity=100, timeout=60, is_deepcopy=False, mutex_update=False)
215
+ def get_concurrent_update_cache_data():
216
+ time.sleep(3)
217
+ return {}
218
+
219
+
220
+ @k3cacheable.cache("mutex_update_cache_data", capacity=100, timeout=60, is_deepcopy=False, mutex_update=True)
221
+ def get_mutex_update_cache_data():
222
+ time.sleep(3)
223
+ return {}
224
+
225
+
226
+ need_cache_data = {
227
+ "key1": {"tm": 0},
228
+ "key2": {"tm": 0},
229
+ "key3": {"tm": 0},
230
+ "key4": {"tm": 0},
231
+ }
@@ -1,107 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: k3cacheable
3
- Version: 0.1.0
4
- Summary: Cache data which access frequently.
5
- Home-page: https://github.com/pykit3/k3cacheable
6
- Author: Zhang Yanpo
7
- Author-email: drdr.xp@gmail.com
8
- License: MIT
9
- Description: # k3cacheable
10
-
11
- [![Action-CI](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml/badge.svg)](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml)
12
- [![Build Status](https://travis-ci.com/pykit3/k3cacheable.svg?branch=master)](https://travis-ci.com/pykit3/k3cacheable)
13
- [![Documentation Status](https://readthedocs.org/projects/k3cacheable/badge/?version=stable)](https://k3cacheable.readthedocs.io/en/stable/?badge=stable)
14
- [![Package](https://img.shields.io/pypi/pyversions/k3cacheable)](https://pypi.org/project/k3cacheable)
15
-
16
- Cache data which access frequently.
17
-
18
- k3cacheable is a component of [pykit3] project: a python3 toolkit set.
19
-
20
-
21
- Cache data which access frequently.
22
-
23
-
24
-
25
-
26
- # Install
27
-
28
- ```
29
- pip install k3cacheable
30
- ```
31
-
32
- # Synopsis
33
-
34
- ```python
35
-
36
- import k3cacheable
37
- import time
38
-
39
- # create a `LRU`, capacity:10 timeout:60
40
- c = k3cacheable.LRU(10, 60)
41
-
42
- # set value like the `dict`
43
- c['key'] = 'val'
44
-
45
- # get value like the `dict`
46
- # if item timeout, delete it and raise `KeyError`
47
- # if item not exist, raise `KeyError`
48
- try:
49
- val = c['key']
50
- except KeyError:
51
- print('key error')
52
-
53
- cache_data = {
54
- 'key1': 'val_1',
55
- 'key2': 'val_2',
56
- }
57
-
58
- # define the function with a decorator
59
- @k3cacheable.cache('cache_name', capacity=100, timeout=60,
60
- is_deepcopy=False, mutex_update=False)
61
- def get_data(param):
62
- return cache_data.get(param, '')
63
-
64
- # call `get_data`, if item has not been cached, cache the return value
65
- data = get_data('key1')
66
-
67
- # call `get_data` use the same param, data will be got from cache
68
- time.sleep(1)
69
- data = get_data('key1')
70
-
71
- # if item timeout, when call `get_data`, cache again
72
- time.sleep(1)
73
- data = get_data('key1')
74
-
75
- # define a method with a decorator
76
- class MethodCache(object):
77
-
78
- @k3cacheable.cache('method_cache_name', capacity=100, timeout=60,
79
- is_deepcopy=False, mutex_update=False)
80
- def get_data(self, param):
81
- return cache_data.get(param, '')
82
-
83
- mm = MethodCache()
84
- data = mm.get_data('key2')
85
-
86
- ```
87
-
88
- # Author
89
-
90
- Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>
91
-
92
- # Copyright and License
93
-
94
- The MIT License (MIT)
95
-
96
- Copyright (c) 2015 Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>
97
-
98
-
99
- [pykit3]: https://github.com/pykit3
100
- Keywords: python,cache
101
- Platform: UNKNOWN
102
- Classifier: Development Status :: 4 - Beta
103
- Classifier: Intended Audience :: Developers
104
- Classifier: Topic :: Software Development :: Libraries
105
- Classifier: Programming Language :: Python :: 3
106
- Requires-Python: >=3.0
107
- Description-Content-Type: text/markdown
@@ -1,23 +0,0 @@
1
- # DO NOT EDIT!!! built with `python _building/build_setup.py`
2
- import setuptools
3
- setuptools.setup(
4
- name="k3cacheable",
5
- packages=["k3cacheable"],
6
- version="0.1.0",
7
- license='MIT',
8
- description='Cache data which access frequently.',
9
- long_description="# k3cacheable\n\n[![Action-CI](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml/badge.svg)](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml)\n[![Build Status](https://travis-ci.com/pykit3/k3cacheable.svg?branch=master)](https://travis-ci.com/pykit3/k3cacheable)\n[![Documentation Status](https://readthedocs.org/projects/k3cacheable/badge/?version=stable)](https://k3cacheable.readthedocs.io/en/stable/?badge=stable)\n[![Package](https://img.shields.io/pypi/pyversions/k3cacheable)](https://pypi.org/project/k3cacheable)\n\nCache data which access frequently.\n\nk3cacheable is a component of [pykit3] project: a python3 toolkit set.\n\n\nCache data which access frequently.\n\n\n\n\n# Install\n\n```\npip install k3cacheable\n```\n\n# Synopsis\n\n```python\n\nimport k3cacheable\nimport time\n\n# create a `LRU`, capacity:10 timeout:60\nc = k3cacheable.LRU(10, 60)\n\n# set value like the `dict`\nc['key'] = 'val'\n\n# get value like the `dict`\n# if item timeout, delete it and raise `KeyError`\n# if item not exist, raise `KeyError`\ntry:\n val = c['key']\nexcept KeyError:\n print('key error')\n\ncache_data = {\n 'key1': 'val_1',\n 'key2': 'val_2',\n}\n\n# define the function with a decorator\n@k3cacheable.cache('cache_name', capacity=100, timeout=60,\n is_deepcopy=False, mutex_update=False)\ndef get_data(param):\n return cache_data.get(param, '')\n\n# call `get_data`, if item has not been cached, cache the return value\ndata = get_data('key1')\n\n# call `get_data` use the same param, data will be got from cache\ntime.sleep(1)\ndata = get_data('key1')\n\n# if item timeout, when call `get_data`, cache again\ntime.sleep(1)\ndata = get_data('key1')\n\n# define a method with a decorator\nclass MethodCache(object):\n\n @k3cacheable.cache('method_cache_name', capacity=100, timeout=60,\n is_deepcopy=False, mutex_update=False)\n def get_data(self, param):\n return cache_data.get(param, '')\n\nmm = MethodCache()\ndata = mm.get_data('key2')\n\n```\n\n# Author\n\nZhang Yanpo (张炎泼) <drdr.xp@gmail.com>\n\n# Copyright and License\n\nThe MIT License (MIT)\n\nCopyright (c) 2015 Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>\n\n\n[pykit3]: https://github.com/pykit3",
10
- long_description_content_type="text/markdown",
11
- author='Zhang Yanpo',
12
- author_email='drdr.xp@gmail.com',
13
- url='https://github.com/pykit3/k3cacheable',
14
- keywords=['python', 'cache'],
15
- python_requires='>=3.0',
16
-
17
- install_requires=['msgpack>=1.0.0'],
18
- classifiers=[
19
- 'Development Status :: 4 - Beta',
20
- 'Intended Audience :: Developers',
21
- 'Topic :: Software Development :: Libraries',
22
- ] + ['Programming Language :: Python :: 3'],
23
- )
@@ -1,107 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: k3cacheable
3
- Version: 0.1.0
4
- Summary: Cache data which access frequently.
5
- Home-page: https://github.com/pykit3/k3cacheable
6
- Author: Zhang Yanpo
7
- Author-email: drdr.xp@gmail.com
8
- License: MIT
9
- Description: # k3cacheable
10
-
11
- [![Action-CI](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml/badge.svg)](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml)
12
- [![Build Status](https://travis-ci.com/pykit3/k3cacheable.svg?branch=master)](https://travis-ci.com/pykit3/k3cacheable)
13
- [![Documentation Status](https://readthedocs.org/projects/k3cacheable/badge/?version=stable)](https://k3cacheable.readthedocs.io/en/stable/?badge=stable)
14
- [![Package](https://img.shields.io/pypi/pyversions/k3cacheable)](https://pypi.org/project/k3cacheable)
15
-
16
- Cache data which access frequently.
17
-
18
- k3cacheable is a component of [pykit3] project: a python3 toolkit set.
19
-
20
-
21
- Cache data which access frequently.
22
-
23
-
24
-
25
-
26
- # Install
27
-
28
- ```
29
- pip install k3cacheable
30
- ```
31
-
32
- # Synopsis
33
-
34
- ```python
35
-
36
- import k3cacheable
37
- import time
38
-
39
- # create a `LRU`, capacity:10 timeout:60
40
- c = k3cacheable.LRU(10, 60)
41
-
42
- # set value like the `dict`
43
- c['key'] = 'val'
44
-
45
- # get value like the `dict`
46
- # if item timeout, delete it and raise `KeyError`
47
- # if item not exist, raise `KeyError`
48
- try:
49
- val = c['key']
50
- except KeyError:
51
- print('key error')
52
-
53
- cache_data = {
54
- 'key1': 'val_1',
55
- 'key2': 'val_2',
56
- }
57
-
58
- # define the function with a decorator
59
- @k3cacheable.cache('cache_name', capacity=100, timeout=60,
60
- is_deepcopy=False, mutex_update=False)
61
- def get_data(param):
62
- return cache_data.get(param, '')
63
-
64
- # call `get_data`, if item has not been cached, cache the return value
65
- data = get_data('key1')
66
-
67
- # call `get_data` use the same param, data will be got from cache
68
- time.sleep(1)
69
- data = get_data('key1')
70
-
71
- # if item timeout, when call `get_data`, cache again
72
- time.sleep(1)
73
- data = get_data('key1')
74
-
75
- # define a method with a decorator
76
- class MethodCache(object):
77
-
78
- @k3cacheable.cache('method_cache_name', capacity=100, timeout=60,
79
- is_deepcopy=False, mutex_update=False)
80
- def get_data(self, param):
81
- return cache_data.get(param, '')
82
-
83
- mm = MethodCache()
84
- data = mm.get_data('key2')
85
-
86
- ```
87
-
88
- # Author
89
-
90
- Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>
91
-
92
- # Copyright and License
93
-
94
- The MIT License (MIT)
95
-
96
- Copyright (c) 2015 Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>
97
-
98
-
99
- [pykit3]: https://github.com/pykit3
100
- Keywords: python,cache
101
- Platform: UNKNOWN
102
- Classifier: Development Status :: 4 - Beta
103
- Classifier: Intended Audience :: Developers
104
- Classifier: Topic :: Software Development :: Libraries
105
- Classifier: Programming Language :: Python :: 3
106
- Requires-Python: >=3.0
107
- Description-Content-Type: text/markdown
@@ -1,10 +0,0 @@
1
- setup.py
2
- k3cacheable/__init__.py
3
- k3cacheable/cacheable.py
4
- k3cacheable/setup.py
5
- k3cacheable/synopsis.py
6
- k3cacheable.egg-info/PKG-INFO
7
- k3cacheable.egg-info/SOURCES.txt
8
- k3cacheable.egg-info/dependency_links.txt
9
- k3cacheable.egg-info/requires.txt
10
- k3cacheable.egg-info/top_level.txt
@@ -1 +0,0 @@
1
- msgpack>=1.0.0
@@ -1,23 +0,0 @@
1
- # DO NOT EDIT!!! built with `python _building/build_setup.py`
2
- import setuptools
3
- setuptools.setup(
4
- name="k3cacheable",
5
- packages=["k3cacheable"],
6
- version="0.1.0",
7
- license='MIT',
8
- description='Cache data which access frequently.',
9
- long_description="# k3cacheable\n\n[![Action-CI](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml/badge.svg)](https://github.com/pykit3/k3cacheable/actions/workflows/python-package.yml)\n[![Build Status](https://travis-ci.com/pykit3/k3cacheable.svg?branch=master)](https://travis-ci.com/pykit3/k3cacheable)\n[![Documentation Status](https://readthedocs.org/projects/k3cacheable/badge/?version=stable)](https://k3cacheable.readthedocs.io/en/stable/?badge=stable)\n[![Package](https://img.shields.io/pypi/pyversions/k3cacheable)](https://pypi.org/project/k3cacheable)\n\nCache data which access frequently.\n\nk3cacheable is a component of [pykit3] project: a python3 toolkit set.\n\n\nCache data which access frequently.\n\n\n\n\n# Install\n\n```\npip install k3cacheable\n```\n\n# Synopsis\n\n```python\n\nimport k3cacheable\nimport time\n\n# create a `LRU`, capacity:10 timeout:60\nc = k3cacheable.LRU(10, 60)\n\n# set value like the `dict`\nc['key'] = 'val'\n\n# get value like the `dict`\n# if item timeout, delete it and raise `KeyError`\n# if item not exist, raise `KeyError`\ntry:\n val = c['key']\nexcept KeyError:\n print('key error')\n\ncache_data = {\n 'key1': 'val_1',\n 'key2': 'val_2',\n}\n\n# define the function with a decorator\n@k3cacheable.cache('cache_name', capacity=100, timeout=60,\n is_deepcopy=False, mutex_update=False)\ndef get_data(param):\n return cache_data.get(param, '')\n\n# call `get_data`, if item has not been cached, cache the return value\ndata = get_data('key1')\n\n# call `get_data` use the same param, data will be got from cache\ntime.sleep(1)\ndata = get_data('key1')\n\n# if item timeout, when call `get_data`, cache again\ntime.sleep(1)\ndata = get_data('key1')\n\n# define a method with a decorator\nclass MethodCache(object):\n\n @k3cacheable.cache('method_cache_name', capacity=100, timeout=60,\n is_deepcopy=False, mutex_update=False)\n def get_data(self, param):\n return cache_data.get(param, '')\n\nmm = MethodCache()\ndata = mm.get_data('key2')\n\n```\n\n# Author\n\nZhang Yanpo (张炎泼) <drdr.xp@gmail.com>\n\n# Copyright and License\n\nThe MIT License (MIT)\n\nCopyright (c) 2015 Zhang Yanpo (张炎泼) <drdr.xp@gmail.com>\n\n\n[pykit3]: https://github.com/pykit3",
10
- long_description_content_type="text/markdown",
11
- author='Zhang Yanpo',
12
- author_email='drdr.xp@gmail.com',
13
- url='https://github.com/pykit3/k3cacheable',
14
- keywords=['python', 'cache'],
15
- python_requires='>=3.0',
16
-
17
- install_requires=['msgpack>=1.0.0'],
18
- classifiers=[
19
- 'Development Status :: 4 - Beta',
20
- 'Intended Audience :: Developers',
21
- 'Topic :: Software Development :: Libraries',
22
- ] + ['Programming Language :: Python :: 3'],
23
- )
File without changes