bda.cache 1.3.0__tar.gz → 2.0.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.
- bda_cache-2.0.0/.gitignore +12 -0
- bda_cache-2.0.0/CHANGES.rst +85 -0
- bda_cache-2.0.0/PKG-INFO +197 -0
- {bda.cache-1.3.0 → bda_cache-2.0.0}/README.rst +13 -2
- bda_cache-2.0.0/pyproject.toml +85 -0
- bda_cache-2.0.0/src/bda/cache/__init__.py +14 -0
- {bda.cache-1.3.0 → bda_cache-2.0.0}/src/bda/cache/fscache.py +26 -41
- {bda.cache-1.3.0 → bda_cache-2.0.0}/src/bda/cache/interfaces.py +14 -28
- {bda.cache-1.3.0 → bda_cache-2.0.0}/src/bda/cache/memcached.py +12 -14
- {bda.cache-1.3.0 → bda_cache-2.0.0}/src/bda/cache/nullcache.py +5 -10
- bda_cache-2.0.0/src/bda/cache/tests/test_fscache.py +236 -0
- bda_cache-2.0.0/src/bda/cache/tests/test_memcached.py +231 -0
- bda_cache-2.0.0/src/bda/cache/tests/test_nullcache.py +61 -0
- bda.cache-1.3.0/CHANGES.rst +0 -47
- bda.cache-1.3.0/MANIFEST.in +0 -7
- bda.cache-1.3.0/PKG-INFO +0 -140
- bda.cache-1.3.0/buildout.cfg +0 -26
- bda.cache-1.3.0/pyproject.toml +0 -12
- bda.cache-1.3.0/requirements.txt +0 -2
- bda.cache-1.3.0/setup.cfg +0 -13
- bda.cache-1.3.0/setup.py +0 -55
- bda.cache-1.3.0/src/bda/__init__.py +0 -2
- bda.cache-1.3.0/src/bda/cache/__init__.py +0 -14
- bda.cache-1.3.0/src/bda/cache/fscache.txt +0 -190
- bda.cache-1.3.0/src/bda/cache/memcached.txt +0 -142
- bda.cache-1.3.0/src/bda/cache/nullcache.txt +0 -37
- bda.cache-1.3.0/src/bda/cache/tests/test_cache.py +0 -47
- bda.cache-1.3.0/src/bda.cache.egg-info/PKG-INFO +0 -140
- bda.cache-1.3.0/src/bda.cache.egg-info/SOURCES.txt +0 -28
- bda.cache-1.3.0/src/bda.cache.egg-info/dependency_links.txt +0 -1
- bda.cache-1.3.0/src/bda.cache.egg-info/entry_points.txt +0 -2
- bda.cache-1.3.0/src/bda.cache.egg-info/namespace_packages.txt +0 -1
- bda.cache-1.3.0/src/bda.cache.egg-info/not-zip-safe +0 -1
- bda.cache-1.3.0/src/bda.cache.egg-info/requires.txt +0 -13
- bda.cache-1.3.0/src/bda.cache.egg-info/top_level.txt +0 -1
- {bda.cache-1.3.0 → bda_cache-2.0.0}/src/bda/cache/configure.zcml +0 -0
- {bda.cache-1.3.0 → bda_cache-2.0.0}/src/bda/cache/tests/__init__.py +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
Changes
|
|
2
|
+
=======
|
|
3
|
+
|
|
4
|
+
2.0.0 (2026-10-31)
|
|
5
|
+
------------------
|
|
6
|
+
|
|
7
|
+
- Fix the client library selection in ``bda.cache.memcached`` if both
|
|
8
|
+
``libmc`` and ``pylibmc`` are installed. ``pylibmc.Client`` was initialized
|
|
9
|
+
with the ``libmc`` arguments. ``libmc`` is preferred now, as intended.
|
|
10
|
+
[rnix]
|
|
11
|
+
|
|
12
|
+
- Drop the Python 2 remnants: the ``six`` imports in ``bda.cache.fscache``
|
|
13
|
+
and ``bda.cache.memcached`` (``six`` never was a declared dependency),
|
|
14
|
+
``class X(object)`` and the ``IOError`` alias. Remove the unreachable code
|
|
15
|
+
in ``FSCache.__delitem__`` and the unused ``ICacheProvider`` import in
|
|
16
|
+
``bda.cache.memcached``. Behaviour unchanged.
|
|
17
|
+
[rnix]
|
|
18
|
+
|
|
19
|
+
- Convert the doctests to unittest tests and use pytest as test runner. The
|
|
20
|
+
memcached tests use a fake client and no longer need a running memcached
|
|
21
|
+
server. Drop the ``interlude`` and ``zope.testing`` test dependencies.
|
|
22
|
+
[rnix]
|
|
23
|
+
|
|
24
|
+
- Sort the imports with ruff (one per line, ``from`` imports first, no
|
|
25
|
+
sections) and format the code with ``ruff format`` (90 characters per line,
|
|
26
|
+
single quotes).
|
|
27
|
+
[rnix]
|
|
28
|
+
|
|
29
|
+
- Add ``Makefile`` (mxmake) with ``qa.ruff``, ``qa.test`` and ``qa.coverage``
|
|
30
|
+
domains, pin the ruff configuration in ``pyproject.toml`` and add a GitHub
|
|
31
|
+
Actions test workflow.
|
|
32
|
+
[rnix]
|
|
33
|
+
|
|
34
|
+
- Refactor package layout to use ``pyproject.toml`` and implicit namespace
|
|
35
|
+
packages.
|
|
36
|
+
[rnix]
|
|
37
|
+
|
|
38
|
+
- Drop Python 2 support. Python >= 3.10 is required.
|
|
39
|
+
[rnix]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
1.3.0 (2019-02-05)
|
|
43
|
+
------------------
|
|
44
|
+
|
|
45
|
+
- Python 3 comaptibility [reinhardt]
|
|
46
|
+
|
|
47
|
+
- Code style (black/isort) [jensens]
|
|
48
|
+
|
|
49
|
+
1.2.0 (2017-10-19)
|
|
50
|
+
------------------
|
|
51
|
+
|
|
52
|
+
- Change to use libmc or pylibmc when available
|
|
53
|
+
|
|
54
|
+
- Add option to require with bda.cache[pylibmc] or bda.cache[libmc]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
1.1.2 (2009-02-10)
|
|
58
|
+
------------------
|
|
59
|
+
|
|
60
|
+
- remove legacy code
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
1.1.1 (2009-02-10)
|
|
64
|
+
------------------
|
|
65
|
+
|
|
66
|
+
- bugfix in zcml configuration.
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
1.1 (2009-02-09)
|
|
70
|
+
----------------
|
|
71
|
+
|
|
72
|
+
- Cache Managers are now adapters.
|
|
73
|
+
|
|
74
|
+
- Implement memcached server support
|
|
75
|
+
|
|
76
|
+
- deprecate the default CacheManager
|
|
77
|
+
|
|
78
|
+
- Fix tests for FSCache
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
1.0
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
- Initial work
|
|
85
|
+
|
bda_cache-2.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: bda.cache
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Simple caching infrastructure.
|
|
5
|
+
Project-URL: Homepage, https://github.com/bluedynamics/bda.cache
|
|
6
|
+
Author-email: Robert Niederreiter <rnix@squarewave.at>
|
|
7
|
+
License: GNU General Public License v2 or later (GPLv2+)
|
|
8
|
+
Keywords: caching,fscache,memcached,zca,zope
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Environment :: Web Environment
|
|
11
|
+
Classifier: License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Requires-Dist: python-memcached
|
|
22
|
+
Requires-Dist: zope-component
|
|
23
|
+
Provides-Extra: libmc
|
|
24
|
+
Requires-Dist: libmc; extra == 'libmc'
|
|
25
|
+
Provides-Extra: pylibmc
|
|
26
|
+
Requires-Dist: pylibmc; extra == 'pylibmc'
|
|
27
|
+
Provides-Extra: test
|
|
28
|
+
Requires-Dist: pytest; extra == 'test'
|
|
29
|
+
Description-Content-Type: text/x-rst
|
|
30
|
+
|
|
31
|
+
.. image:: https://img.shields.io/pypi/v/bda.cache.svg
|
|
32
|
+
:target: https://pypi.python.org/pypi/bda.cache
|
|
33
|
+
:alt: Latest PyPI version
|
|
34
|
+
|
|
35
|
+
.. image:: https://img.shields.io/pypi/dm/bda.cache.svg
|
|
36
|
+
:target: https://pypi.python.org/pypi/bda.cache
|
|
37
|
+
:alt: Number of PyPI downloads
|
|
38
|
+
|
|
39
|
+
.. image:: https://github.com/bluedynamics/bda.cache/actions/workflows/test.yml/badge.svg
|
|
40
|
+
:target: https://github.com/bluedynamics/bda.cache/actions/workflows/test.yml
|
|
41
|
+
:alt: Test bda.cache
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
General Caching API
|
|
45
|
+
===================
|
|
46
|
+
|
|
47
|
+
This package is designed to be used by applications which require different
|
|
48
|
+
kinds of caching flavour. This is abstracted due to the interfaces
|
|
49
|
+
``ICacheProvider`` and ``ICacheManager``. ICacheProvider takes care of the
|
|
50
|
+
concrete cache implementation, ICacheManager is the read/write interface.
|
|
51
|
+
|
|
52
|
+
The convention is to adapt a concrete ICacheProvider implementation
|
|
53
|
+
|
|
54
|
+
.. code-block:: python
|
|
55
|
+
|
|
56
|
+
from bda.cache import ICacheManager
|
|
57
|
+
from bda.cache import Memcached
|
|
58
|
+
|
|
59
|
+
provider = Memcached(['127.0.0.1:11211'])
|
|
60
|
+
manager = ICacheManager(provider)
|
|
61
|
+
|
|
62
|
+
We can ask the manager for data inside the cache
|
|
63
|
+
|
|
64
|
+
.. code-block:: python
|
|
65
|
+
|
|
66
|
+
data = manager.get('somekey', force_reload=False)
|
|
67
|
+
|
|
68
|
+
If ``force_reload`` is set to True, try to delete data with key from cache and
|
|
69
|
+
return None.
|
|
70
|
+
|
|
71
|
+
We're also able to manipulate the cache's data (some restrictions my result out
|
|
72
|
+
of backend not providing them)
|
|
73
|
+
|
|
74
|
+
.. code-block:: python
|
|
75
|
+
|
|
76
|
+
manager.set('somekey', object())
|
|
77
|
+
|
|
78
|
+
There exist a convenience to use some API's and cache it's results all at once.
|
|
79
|
+
|
|
80
|
+
.. code-block:: python
|
|
81
|
+
|
|
82
|
+
data = manager.getData(func, key, force_reload=False, args=[], kwargs={})
|
|
83
|
+
|
|
84
|
+
First the data for ``key`` is looked up inside the cache provider. If not found
|
|
85
|
+
there or if ``force_reload`` is set to True, call given ``func`` . The return
|
|
86
|
+
value of this function will be stored in the cache provider. ``args`` and
|
|
87
|
+
``kwargs`` are passed as parameters to given function if it's call is required.
|
|
88
|
+
|
|
89
|
+
You might ask why all this is done due to 2 seperate interfaces...
|
|
90
|
+
|
|
91
|
+
Some usecase might require different cache providers i.e. for different payload
|
|
92
|
+
size. This way you can implement any other cache provider usage as well due to
|
|
93
|
+
the cache manager interface.
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
Dependencies
|
|
97
|
+
------------
|
|
98
|
+
|
|
99
|
+
- ``zope.interface``
|
|
100
|
+
|
|
101
|
+
- ``zope.component``
|
|
102
|
+
|
|
103
|
+
- ``bda.cache.memcached.Memcached`` requires ``python-memcached``
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
Notes
|
|
107
|
+
-----
|
|
108
|
+
|
|
109
|
+
If you're interessted to contribute; Feel free but keep in mind that this code
|
|
110
|
+
is planned to be released under a BSD like licence in future.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
Changes
|
|
114
|
+
=======
|
|
115
|
+
|
|
116
|
+
2.0.0 (2026-10-31)
|
|
117
|
+
------------------
|
|
118
|
+
|
|
119
|
+
- Fix the client library selection in ``bda.cache.memcached`` if both
|
|
120
|
+
``libmc`` and ``pylibmc`` are installed. ``pylibmc.Client`` was initialized
|
|
121
|
+
with the ``libmc`` arguments. ``libmc`` is preferred now, as intended.
|
|
122
|
+
[rnix]
|
|
123
|
+
|
|
124
|
+
- Drop the Python 2 remnants: the ``six`` imports in ``bda.cache.fscache``
|
|
125
|
+
and ``bda.cache.memcached`` (``six`` never was a declared dependency),
|
|
126
|
+
``class X(object)`` and the ``IOError`` alias. Remove the unreachable code
|
|
127
|
+
in ``FSCache.__delitem__`` and the unused ``ICacheProvider`` import in
|
|
128
|
+
``bda.cache.memcached``. Behaviour unchanged.
|
|
129
|
+
[rnix]
|
|
130
|
+
|
|
131
|
+
- Convert the doctests to unittest tests and use pytest as test runner. The
|
|
132
|
+
memcached tests use a fake client and no longer need a running memcached
|
|
133
|
+
server. Drop the ``interlude`` and ``zope.testing`` test dependencies.
|
|
134
|
+
[rnix]
|
|
135
|
+
|
|
136
|
+
- Sort the imports with ruff (one per line, ``from`` imports first, no
|
|
137
|
+
sections) and format the code with ``ruff format`` (90 characters per line,
|
|
138
|
+
single quotes).
|
|
139
|
+
[rnix]
|
|
140
|
+
|
|
141
|
+
- Add ``Makefile`` (mxmake) with ``qa.ruff``, ``qa.test`` and ``qa.coverage``
|
|
142
|
+
domains, pin the ruff configuration in ``pyproject.toml`` and add a GitHub
|
|
143
|
+
Actions test workflow.
|
|
144
|
+
[rnix]
|
|
145
|
+
|
|
146
|
+
- Refactor package layout to use ``pyproject.toml`` and implicit namespace
|
|
147
|
+
packages.
|
|
148
|
+
[rnix]
|
|
149
|
+
|
|
150
|
+
- Drop Python 2 support. Python >= 3.10 is required.
|
|
151
|
+
[rnix]
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
1.3.0 (2019-02-05)
|
|
155
|
+
------------------
|
|
156
|
+
|
|
157
|
+
- Python 3 comaptibility [reinhardt]
|
|
158
|
+
|
|
159
|
+
- Code style (black/isort) [jensens]
|
|
160
|
+
|
|
161
|
+
1.2.0 (2017-10-19)
|
|
162
|
+
------------------
|
|
163
|
+
|
|
164
|
+
- Change to use libmc or pylibmc when available
|
|
165
|
+
|
|
166
|
+
- Add option to require with bda.cache[pylibmc] or bda.cache[libmc]
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
1.1.2 (2009-02-10)
|
|
170
|
+
------------------
|
|
171
|
+
|
|
172
|
+
- remove legacy code
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
1.1.1 (2009-02-10)
|
|
176
|
+
------------------
|
|
177
|
+
|
|
178
|
+
- bugfix in zcml configuration.
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
1.1 (2009-02-09)
|
|
182
|
+
----------------
|
|
183
|
+
|
|
184
|
+
- Cache Managers are now adapters.
|
|
185
|
+
|
|
186
|
+
- Implement memcached server support
|
|
187
|
+
|
|
188
|
+
- deprecate the default CacheManager
|
|
189
|
+
|
|
190
|
+
- Fix tests for FSCache
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
1.0
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
- Initial work
|
|
197
|
+
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
.. image:: https://img.shields.io/pypi/v/bda.cache.svg
|
|
2
|
+
:target: https://pypi.python.org/pypi/bda.cache
|
|
3
|
+
:alt: Latest PyPI version
|
|
4
|
+
|
|
5
|
+
.. image:: https://img.shields.io/pypi/dm/bda.cache.svg
|
|
6
|
+
:target: https://pypi.python.org/pypi/bda.cache
|
|
7
|
+
:alt: Number of PyPI downloads
|
|
8
|
+
|
|
9
|
+
.. image:: https://github.com/bluedynamics/bda.cache/actions/workflows/test.yml/badge.svg
|
|
10
|
+
:target: https://github.com/bluedynamics/bda.cache/actions/workflows/test.yml
|
|
11
|
+
:alt: Test bda.cache
|
|
12
|
+
|
|
13
|
+
|
|
1
14
|
General Caching API
|
|
2
15
|
===================
|
|
3
16
|
|
|
@@ -57,8 +70,6 @@ Dependencies
|
|
|
57
70
|
|
|
58
71
|
- ``zope.component``
|
|
59
72
|
|
|
60
|
-
- ``bda.cache.fscache.FSCache`` recommends that availability of ``cpickle``
|
|
61
|
-
|
|
62
73
|
- ``bda.cache.memcached.Memcached`` requires ``python-memcached``
|
|
63
74
|
|
|
64
75
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling", "hatch-fancy-pypi-readme"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "bda.cache"
|
|
7
|
+
version = "2.0.0"
|
|
8
|
+
description = "Simple caching infrastructure."
|
|
9
|
+
dynamic = ["readme"]
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = {text = "GNU General Public License v2 or later (GPLv2+)"}
|
|
12
|
+
authors = [{name = "Robert Niederreiter", email = "rnix@squarewave.at"}]
|
|
13
|
+
keywords = ["caching", "memcached", "fscache", "zope", "zca"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 5 - Production/Stable",
|
|
16
|
+
"Environment :: Web Environment",
|
|
17
|
+
"License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
|
|
20
|
+
"Programming Language :: Python",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
"Programming Language :: Python :: 3.14",
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"python-memcached",
|
|
29
|
+
"zope.component",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
libmc = ["libmc"]
|
|
34
|
+
pylibmc = ["pylibmc"]
|
|
35
|
+
test = [
|
|
36
|
+
"pytest",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/bluedynamics/bda.cache"
|
|
41
|
+
|
|
42
|
+
[tool.hatch.metadata.hooks.fancy-pypi-readme]
|
|
43
|
+
content-type = "text/x-rst"
|
|
44
|
+
fragments = [
|
|
45
|
+
{path = "README.rst"},
|
|
46
|
+
{text = "\n\n"},
|
|
47
|
+
{path = "CHANGES.rst"},
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[tool.hatch.build.targets.sdist]
|
|
51
|
+
exclude = [
|
|
52
|
+
"/.github/",
|
|
53
|
+
"/Makefile",
|
|
54
|
+
"/mx.ini",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
[tool.hatch.build.targets.wheel]
|
|
58
|
+
packages = ["src/bda"]
|
|
59
|
+
|
|
60
|
+
[tool.pytest.ini_options]
|
|
61
|
+
consider_namespace_packages = true
|
|
62
|
+
addopts = ["--import-mode=importlib"]
|
|
63
|
+
pythonpath = "src"
|
|
64
|
+
|
|
65
|
+
[tool.ruff]
|
|
66
|
+
line-length = 90
|
|
67
|
+
|
|
68
|
+
[tool.ruff.lint]
|
|
69
|
+
select = ["E4", "E7", "E9", "F", "I", "UP"]
|
|
70
|
+
# UP008: zero-argument ``super()`` breaks on ``@plumbing`` decorated classes.
|
|
71
|
+
# UP031: ``%`` formatting is kept.
|
|
72
|
+
ignore = ["UP008", "UP031"]
|
|
73
|
+
|
|
74
|
+
[tool.ruff.lint.isort]
|
|
75
|
+
force-single-line = true
|
|
76
|
+
from-first = true
|
|
77
|
+
no-sections = true
|
|
78
|
+
lines-after-imports = 2
|
|
79
|
+
order-by-type = false
|
|
80
|
+
|
|
81
|
+
[tool.ruff.format]
|
|
82
|
+
quote-style = "single"
|
|
83
|
+
|
|
84
|
+
[tool.zest-releaser]
|
|
85
|
+
create-wheel = true
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Copyright 2009, Blue Dynamics Alliance, Austria - http://bluedynamics.com
|
|
2
|
+
# GNU General Public Licence Version 2 or later
|
|
3
|
+
|
|
4
|
+
from bda.cache.fscache import FSCache # noqa
|
|
5
|
+
from bda.cache.fscache import FSCacheException # noqa
|
|
6
|
+
from bda.cache.fscache import FSCacheManager # noqa
|
|
7
|
+
from bda.cache.interfaces import ICacheManager # noqa
|
|
8
|
+
from bda.cache.interfaces import ICacheProvider # noqa
|
|
9
|
+
from bda.cache.interfaces import ICacheVary # noqa
|
|
10
|
+
from bda.cache.memcached import Memcached # noqa
|
|
11
|
+
from bda.cache.memcached import MemcachedException # noqa
|
|
12
|
+
from bda.cache.memcached import MemcachedManager # noqa
|
|
13
|
+
from bda.cache.nullcache import NullCache # noqa
|
|
14
|
+
from bda.cache.nullcache import NullCacheManager # noqa
|
|
@@ -5,39 +5,28 @@ Module fscache.
|
|
|
5
5
|
|
|
6
6
|
This module provides fuctionallity for caching objects on the filesystem.
|
|
7
7
|
|
|
8
|
-
Therefor it uses
|
|
8
|
+
Therefor it uses pickle.
|
|
9
9
|
|
|
10
10
|
This module was originally designed for very simple caching tasks like caching
|
|
11
11
|
mail headers in a MUA or similar. It is NOT a cache manager.
|
|
12
12
|
|
|
13
13
|
If you find this module useful and you have some improvements or bugfixes,
|
|
14
14
|
please contact the author.
|
|
15
|
-
|
|
16
|
-
This module is tested on linux with python 2.4. If you are running in troubles
|
|
17
|
-
when using another operating system or python version, please contact the
|
|
18
|
-
author.
|
|
19
15
|
"""
|
|
20
16
|
|
|
21
|
-
try:
|
|
22
|
-
import six.moves.cPickle as pickle
|
|
23
|
-
except:
|
|
24
|
-
import pickle
|
|
25
|
-
|
|
26
|
-
|
|
27
17
|
from bda.cache.interfaces import CacheException
|
|
28
18
|
from bda.cache.interfaces import ICacheManager
|
|
29
19
|
from bda.cache.interfaces import IFSCacheProvider
|
|
30
|
-
from six.moves import range
|
|
31
20
|
from zope.component import adapter
|
|
32
21
|
from zope.component import provideAdapter
|
|
33
22
|
from zope.interface import implementer
|
|
34
|
-
|
|
35
23
|
import logging
|
|
36
24
|
import os
|
|
25
|
+
import pickle
|
|
37
26
|
import time
|
|
38
27
|
|
|
39
28
|
|
|
40
|
-
logger = logging.getLogger(
|
|
29
|
+
logger = logging.getLogger('bda.cache.cachemanager')
|
|
41
30
|
|
|
42
31
|
|
|
43
32
|
class FSCacheException(CacheException):
|
|
@@ -45,7 +34,7 @@ class FSCacheException(CacheException):
|
|
|
45
34
|
|
|
46
35
|
|
|
47
36
|
@implementer(IFSCacheProvider)
|
|
48
|
-
class FSCache
|
|
37
|
+
class FSCache:
|
|
49
38
|
"""Class FsCache.
|
|
50
39
|
|
|
51
40
|
Simple object caching.
|
|
@@ -124,9 +113,8 @@ class FSCache(object):
|
|
|
124
113
|
return self._getitem(key)
|
|
125
114
|
|
|
126
115
|
def __setitem__(self, key, object):
|
|
127
|
-
"""Read the class documentation how keys must look like.
|
|
128
|
-
|
|
129
|
-
objpath = key.split(".")
|
|
116
|
+
"""Read the class documentation how keys must look like."""
|
|
117
|
+
objpath = key.split('.')
|
|
130
118
|
objlen = len(objpath)
|
|
131
119
|
pt = 1
|
|
132
120
|
path = self.cachedir
|
|
@@ -136,14 +124,14 @@ class FSCache(object):
|
|
|
136
124
|
if not exists:
|
|
137
125
|
os.mkdir(path)
|
|
138
126
|
pt += 1
|
|
139
|
-
path = os.path.join(path,
|
|
140
|
-
file = open(path,
|
|
127
|
+
path = os.path.join(path, '%s.' % objpath[-1])
|
|
128
|
+
file = open(path, 'wb')
|
|
141
129
|
pickle.dump(object, file, self.protocol)
|
|
142
130
|
file.close()
|
|
143
131
|
|
|
144
132
|
def __delitem__(self, key):
|
|
145
|
-
path = key.split(
|
|
146
|
-
path[-1] =
|
|
133
|
+
path = key.split('.')
|
|
134
|
+
path[-1] = '%s.' % path[-1]
|
|
147
135
|
try:
|
|
148
136
|
os.remove(os.path.join(self.cachedir, *path))
|
|
149
137
|
except OSError:
|
|
@@ -151,8 +139,6 @@ class FSCache(object):
|
|
|
151
139
|
pt = len(path) - 1
|
|
152
140
|
while pt > 0:
|
|
153
141
|
previous = path[:pt]
|
|
154
|
-
if not previous:
|
|
155
|
-
return None
|
|
156
142
|
curpath = os.path.join(self.cachedir, *previous)
|
|
157
143
|
contents = os.listdir(curpath)
|
|
158
144
|
if not contents:
|
|
@@ -163,10 +149,10 @@ class FSCache(object):
|
|
|
163
149
|
return None
|
|
164
150
|
|
|
165
151
|
def _getitem(self, key, default=None):
|
|
166
|
-
path =
|
|
152
|
+
path = '%s.' % os.path.join(self.cachedir, *key.split('.'))
|
|
167
153
|
try:
|
|
168
|
-
file = open(path,
|
|
169
|
-
except
|
|
154
|
+
file = open(path, 'rb')
|
|
155
|
+
except OSError:
|
|
170
156
|
return default
|
|
171
157
|
obj = pickle.load(file)
|
|
172
158
|
file.close()
|
|
@@ -175,11 +161,11 @@ class FSCache(object):
|
|
|
175
161
|
def _readkeys(self, keys, path=[]):
|
|
176
162
|
entries = os.listdir(os.path.join(self.cachedir, *path))
|
|
177
163
|
for entry in entries:
|
|
178
|
-
if entry[-1] ==
|
|
179
|
-
key =
|
|
164
|
+
if entry[-1] == '.':
|
|
165
|
+
key = ''
|
|
180
166
|
for part in path:
|
|
181
|
-
key =
|
|
182
|
-
keys.append(
|
|
167
|
+
key = '%s%s.' % (key, part)
|
|
168
|
+
keys.append('%s%s' % (key, entry[: len(entry) - 1]))
|
|
183
169
|
else:
|
|
184
170
|
self._readkeys(keys, path + [entry])
|
|
185
171
|
return keys
|
|
@@ -195,7 +181,7 @@ class FSCache(object):
|
|
|
195
181
|
|
|
196
182
|
@implementer(ICacheManager)
|
|
197
183
|
@adapter(IFSCacheProvider)
|
|
198
|
-
class FSCacheManager
|
|
184
|
+
class FSCacheManager:
|
|
199
185
|
def __init__(self, context):
|
|
200
186
|
self.timeout = 300 # defaults to 300 seconds
|
|
201
187
|
self.cache = context
|
|
@@ -215,10 +201,10 @@ class FSCacheManager(object):
|
|
|
215
201
|
def get(self, key, force_reload=False):
|
|
216
202
|
if force_reload or self._isTimedOut(key):
|
|
217
203
|
del self.cache[key]
|
|
218
|
-
creationmap = self.cache.get(
|
|
204
|
+
creationmap = self.cache.get('creationmap', None)
|
|
219
205
|
if creationmap is not None and key in creationmap:
|
|
220
206
|
del creationmap[key]
|
|
221
|
-
self.cache[
|
|
207
|
+
self.cache['creationmap'] = creationmap
|
|
222
208
|
return None
|
|
223
209
|
return self.cache.get(key, None)
|
|
224
210
|
|
|
@@ -226,27 +212,26 @@ class FSCacheManager(object):
|
|
|
226
212
|
self.cache[key] = item
|
|
227
213
|
if not set_creationtime:
|
|
228
214
|
return
|
|
229
|
-
creationmap = self.cache.get(
|
|
215
|
+
creationmap = self.cache.get('creationmap', None)
|
|
230
216
|
if not creationmap:
|
|
231
217
|
creationmap = dict()
|
|
232
218
|
creationmap[key] = time.time()
|
|
233
|
-
self.cache[
|
|
219
|
+
self.cache['creationmap'] = creationmap
|
|
234
220
|
|
|
235
221
|
def rem(self, key):
|
|
236
222
|
del self.cache[key]
|
|
237
|
-
creationmap = self.cache.get(
|
|
223
|
+
creationmap = self.cache.get('creationmap', None)
|
|
238
224
|
if creationmap is not None and key in creationmap:
|
|
239
225
|
del creationmap[key]
|
|
240
|
-
self.cache[
|
|
226
|
+
self.cache['creationmap'] = creationmap
|
|
241
227
|
|
|
242
228
|
def __delitem__(self, key):
|
|
243
229
|
self.rem(key)
|
|
244
230
|
|
|
245
231
|
def _isTimedOut(self, key):
|
|
246
|
-
"""Return wether the item with key is timed out or not.
|
|
247
|
-
"""
|
|
232
|
+
"""Return wether the item with key is timed out or not."""
|
|
248
233
|
cur = time.time()
|
|
249
|
-
creationmap = self.cache.get(
|
|
234
|
+
creationmap = self.cache.get('creationmap', None)
|
|
250
235
|
if not creationmap:
|
|
251
236
|
return True
|
|
252
237
|
creationtime = creationmap.get(key, None)
|
|
@@ -9,12 +9,10 @@ class CacheException(Exception):
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class ICacheVary(Interface):
|
|
12
|
-
"""This interface describes an API for manipulating objects inside a cache.
|
|
13
|
-
"""
|
|
12
|
+
"""This interface describes an API for manipulating objects inside a cache."""
|
|
14
13
|
|
|
15
14
|
def vary(*args, **kwargs):
|
|
16
|
-
"""Manipulate objects inside the cache.
|
|
17
|
-
"""
|
|
15
|
+
"""Manipulate objects inside the cache."""
|
|
18
16
|
|
|
19
17
|
|
|
20
18
|
class ICacheManager(Interface):
|
|
@@ -23,8 +21,7 @@ class ICacheManager(Interface):
|
|
|
23
21
|
"""
|
|
24
22
|
|
|
25
23
|
def setTimeout(timeout):
|
|
26
|
-
"""Set cache timeout in seconds.
|
|
27
|
-
"""
|
|
24
|
+
"""Set cache timeout in seconds."""
|
|
28
25
|
|
|
29
26
|
def getData(func, key, force_reload=False, args=[], kwargs={}):
|
|
30
27
|
"""Convenience to read and cache results at once.
|
|
@@ -55,13 +52,11 @@ class ICacheManager(Interface):
|
|
|
55
52
|
"""
|
|
56
53
|
|
|
57
54
|
def __delitem__(key):
|
|
58
|
-
"""Remove item with key from cache if exists.
|
|
59
|
-
"""
|
|
55
|
+
"""Remove item with key from cache if exists."""
|
|
60
56
|
|
|
61
57
|
|
|
62
58
|
class ICacheProvider(Interface):
|
|
63
|
-
"""This interface describes an API for caching objects.
|
|
64
|
-
"""
|
|
59
|
+
"""This interface describes an API for caching objects."""
|
|
65
60
|
|
|
66
61
|
def reset():
|
|
67
62
|
"""Reset the cache object.
|
|
@@ -70,28 +65,22 @@ class ICacheProvider(Interface):
|
|
|
70
65
|
"""
|
|
71
66
|
|
|
72
67
|
def size():
|
|
73
|
-
"""Return the current size of the cache in byte.
|
|
74
|
-
"""
|
|
68
|
+
"""Return the current size of the cache in byte."""
|
|
75
69
|
|
|
76
70
|
def keys():
|
|
77
|
-
"""Return the keys of the objects contained in this cache as list.
|
|
78
|
-
"""
|
|
71
|
+
"""Return the keys of the objects contained in this cache as list."""
|
|
79
72
|
|
|
80
73
|
def values():
|
|
81
|
-
"""Return objects contained in this cache as list.
|
|
82
|
-
"""
|
|
74
|
+
"""Return objects contained in this cache as list."""
|
|
83
75
|
|
|
84
76
|
def get(key, default=None):
|
|
85
|
-
"""Return object by key or default value if not exist.
|
|
86
|
-
"""
|
|
77
|
+
"""Return object by key or default value if not exist."""
|
|
87
78
|
|
|
88
79
|
def __getitem__(key):
|
|
89
|
-
"""Return object by key or None if not exists.
|
|
90
|
-
"""
|
|
80
|
+
"""Return object by key or None if not exists."""
|
|
91
81
|
|
|
92
82
|
def __setitem__(key, object):
|
|
93
|
-
"""Store object to cache by given key.
|
|
94
|
-
"""
|
|
83
|
+
"""Store object to cache by given key."""
|
|
95
84
|
|
|
96
85
|
def __delitem__(key):
|
|
97
86
|
"""Delete object by key from cache.
|
|
@@ -101,15 +90,12 @@ class ICacheProvider(Interface):
|
|
|
101
90
|
|
|
102
91
|
|
|
103
92
|
class INullCacheProvider(ICacheProvider):
|
|
104
|
-
"""Marker
|
|
105
|
-
"""
|
|
93
|
+
"""Marker"""
|
|
106
94
|
|
|
107
95
|
|
|
108
96
|
class IFSCacheProvider(ICacheProvider):
|
|
109
|
-
"""Marker
|
|
110
|
-
"""
|
|
97
|
+
"""Marker"""
|
|
111
98
|
|
|
112
99
|
|
|
113
100
|
class IMemcachedProvider(ICacheProvider):
|
|
114
|
-
"""Marker
|
|
115
|
-
"""
|
|
101
|
+
"""Marker"""
|