cachier 3.2.1__py3-none-any.whl → 3.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cachier/core.py +51 -3
- cachier/version.info +1 -1
- {cachier-3.2.1.dist-info → cachier-3.3.0.dist-info}/METADATA +23 -1
- {cachier-3.2.1.dist-info → cachier-3.3.0.dist-info}/RECORD +8 -8
- {cachier-3.2.1.dist-info → cachier-3.3.0.dist-info}/WHEEL +0 -0
- {cachier-3.2.1.dist-info → cachier-3.3.0.dist-info}/entry_points.txt +0 -0
- {cachier-3.2.1.dist-info → cachier-3.3.0.dist-info}/licenses/LICENSE +0 -0
- {cachier-3.2.1.dist-info → cachier-3.3.0.dist-info}/top_level.txt +0 -0
cachier/core.py
CHANGED
@@ -31,6 +31,7 @@ from .cores.sql import _SQLCore
|
|
31
31
|
|
32
32
|
MAX_WORKERS_ENVAR_NAME = "CACHIER_MAX_WORKERS"
|
33
33
|
DEFAULT_MAX_WORKERS = 8
|
34
|
+
ZERO_TIMEDELTA = timedelta(seconds=0)
|
34
35
|
|
35
36
|
|
36
37
|
def _max_workers():
|
@@ -225,8 +226,31 @@ def cachier(
|
|
225
226
|
def _cachier_decorator(func):
|
226
227
|
core.set_func(func)
|
227
228
|
|
228
|
-
|
229
|
-
|
229
|
+
# ---
|
230
|
+
# MAINTAINER NOTE: max_age parameter
|
231
|
+
#
|
232
|
+
# The _call function below supports a per-call 'max_age' parameter,
|
233
|
+
# allowing users to specify a maximum allowed age for a cached value.
|
234
|
+
# If the cached value is older than 'max_age',
|
235
|
+
# a recalculation is triggered. This is in addition to the
|
236
|
+
# per-decorator 'stale_after' parameter.
|
237
|
+
#
|
238
|
+
# The effective staleness threshold is the minimum of 'stale_after'
|
239
|
+
# and 'max_age' (if provided).
|
240
|
+
# This ensures that the strictest max age requirement is enforced.
|
241
|
+
#
|
242
|
+
# The main function wrapper is a standard function that passes
|
243
|
+
# *args and **kwargs to _call. By default, max_age is None,
|
244
|
+
# so only 'stale_after' is considered unless overridden.
|
245
|
+
#
|
246
|
+
# The user-facing API exposes:
|
247
|
+
# - Per-call: myfunc(..., max_age=timedelta(...))
|
248
|
+
#
|
249
|
+
# This design allows both one-off (per-call) and default
|
250
|
+
# (per-decorator) max age constraints.
|
251
|
+
# ---
|
252
|
+
|
253
|
+
def _call(*args, max_age: Optional[timedelta] = None, **kwds):
|
230
254
|
nonlocal allow_none
|
231
255
|
_allow_none = _update_with_defaults(allow_none, "allow_none", kwds)
|
232
256
|
# print('Inside general wrapper for {}.'.format(func.__name__))
|
@@ -271,7 +295,23 @@ def cachier(
|
|
271
295
|
if _allow_none or entry.value is not None:
|
272
296
|
_print("Cached result found.")
|
273
297
|
now = datetime.now()
|
274
|
-
|
298
|
+
max_allowed_age = _stale_after
|
299
|
+
nonneg_max_age = True
|
300
|
+
if max_age is not None:
|
301
|
+
if max_age < ZERO_TIMEDELTA:
|
302
|
+
_print(
|
303
|
+
"max_age is negative. "
|
304
|
+
"Cached result considered stale."
|
305
|
+
)
|
306
|
+
nonneg_max_age = False
|
307
|
+
else:
|
308
|
+
max_allowed_age = (
|
309
|
+
min(_stale_after, max_age)
|
310
|
+
if max_age is not None
|
311
|
+
else _stale_after
|
312
|
+
)
|
313
|
+
# note: if max_age < 0, we always consider a value stale
|
314
|
+
if nonneg_max_age and (now - entry.time <= max_allowed_age):
|
275
315
|
_print("And it is fresh!")
|
276
316
|
return entry.value
|
277
317
|
_print("But it is stale... :(")
|
@@ -305,6 +345,14 @@ def cachier(
|
|
305
345
|
_print("No entry found. No current calc. Calling like a boss.")
|
306
346
|
return _calc_entry(core, key, func, args, kwds)
|
307
347
|
|
348
|
+
# MAINTAINER NOTE: The main function wrapper is now a standard function
|
349
|
+
# that passes *args and **kwargs to _call. This ensures that user
|
350
|
+
# arguments are not shifted, and max_age is only settable via keyword
|
351
|
+
# argument.
|
352
|
+
@wraps(func)
|
353
|
+
def func_wrapper(*args, **kwargs):
|
354
|
+
return _call(*args, **kwargs)
|
355
|
+
|
308
356
|
def _clear_cache():
|
309
357
|
"""Clear the cache."""
|
310
358
|
core.clear_cache()
|
cachier/version.info
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.3.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: cachier
|
3
|
-
Version: 3.
|
3
|
+
Version: 3.3.0
|
4
4
|
Summary: Persistent, stale-free, local and cross-machine caching for Python functions.
|
5
5
|
Author-email: Shay Palachy Affek <shay.palachy@gmail.com>
|
6
6
|
License: MIT License
|
@@ -100,6 +100,7 @@ Features
|
|
100
100
|
* Local caching using pickle files.
|
101
101
|
* Cross-machine caching using MongoDB.
|
102
102
|
* Thread-safety.
|
103
|
+
* **Per-call max age:** Specify a maximum age for cached values per call.
|
103
104
|
|
104
105
|
Cachier is **NOT**:
|
105
106
|
|
@@ -282,6 +283,27 @@ Per-function call arguments
|
|
282
283
|
|
283
284
|
Cachier also accepts several keyword arguments in the calls of the function it wraps rather than in the decorator call, allowing you to modify its behaviour for a specific function call.
|
284
285
|
|
286
|
+
**Max Age (max_age)**
|
287
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
288
|
+
You can specify a maximum allowed age for a cached value on a per-call basis using the `max_age` keyword argument. If the cached value is older than this threshold, a recalculation is triggered. This is in addition to the `stale_after` parameter set at the decorator level; the strictest (smallest) threshold is enforced.
|
289
|
+
|
290
|
+
.. code-block:: python
|
291
|
+
|
292
|
+
from datetime import timedelta
|
293
|
+
from cachier import cachier
|
294
|
+
|
295
|
+
@cachier(stale_after=timedelta(days=3))
|
296
|
+
def add(a, b):
|
297
|
+
return a + b
|
298
|
+
|
299
|
+
# Use a per-call max age:
|
300
|
+
result = add(1, 2, max_age=timedelta(seconds=10)) # Only use cache if value is <10s old
|
301
|
+
|
302
|
+
**How it works:**
|
303
|
+
- The effective max age threshold is the minimum of `stale_after` (from the decorator) and `max_age` (from the call).
|
304
|
+
- If the cached value is older than this threshold, a new calculation is triggered and the cache is updated.
|
305
|
+
- If not, the cached value is returned as usual.
|
306
|
+
|
285
307
|
Ignore Cache
|
286
308
|
~~~~~~~~~~~~
|
287
309
|
|
@@ -3,18 +3,18 @@ cachier/__main__.py,sha256=upg-TlHs1vngKYvkjoPpl3Pvl6xOx4ut-M1mElMiAo0,443
|
|
3
3
|
cachier/_types.py,sha256=EGJMiw-oCIC_cDLyzw7YC40lfo8jnD3zMmoJpA9Y8Iw,238
|
4
4
|
cachier/_version.py,sha256=jnPPRn_qmjNi-qmQjlHnzNGf3LSBTYkMmJdGjxMTOBM,1089
|
5
5
|
cachier/config.py,sha256=6hyQtn9T6UXu2UQhKJltWT0Nu4OBS4ION1x7Lt1i8Og,3838
|
6
|
-
cachier/core.py,sha256=
|
6
|
+
cachier/core.py,sha256=PHLDA6Mabih-mi4y3CBsb8_vBIpvYQt547_Y57fo8uI,15825
|
7
7
|
cachier/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
-
cachier/version.info,sha256=
|
8
|
+
cachier/version.info,sha256=Xu5sDFxpAfXlI_CkNLykEG4f9xNt60UfmCsLsaexNxY,6
|
9
9
|
cachier/cores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
cachier/cores/base.py,sha256=s7qgmDJA4LGub6ydGfMk9vVJW4fgeU0EXl-9gmpuh28,3683
|
11
11
|
cachier/cores/memory.py,sha256=fsvqq9rwwmAaMBvYo-oUNAxB6UOyfBpuf8ACW_XTaU0,3572
|
12
12
|
cachier/cores/mongo.py,sha256=pCBrxLsmGr68Q50JVD_CUPAYwhaLDrJUQs_6A-_GYLA,4993
|
13
13
|
cachier/cores/pickle.py,sha256=FgfvZWAFdWQPOo3G-L57iEV2ujEkIDH8TyGzbarsZeE,10678
|
14
14
|
cachier/cores/sql.py,sha256=nuf2-Szo7VTPRa7IC3JGWEtGsBtdkIrx0bhOm3U0mfE,9895
|
15
|
-
cachier-3.
|
16
|
-
cachier-3.
|
17
|
-
cachier-3.
|
18
|
-
cachier-3.
|
19
|
-
cachier-3.
|
20
|
-
cachier-3.
|
15
|
+
cachier-3.3.0.dist-info/licenses/LICENSE,sha256=-2WrMJkIa0gVP6YQHXXDT7ws-S3M2NEVEF4XF3K8qrY,1069
|
16
|
+
cachier-3.3.0.dist-info/METADATA,sha256=P8GoF2LSZKA5Tp8NunrJvS_f1XlytO4HsCmDsUy4oxQ,23136
|
17
|
+
cachier-3.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
18
|
+
cachier-3.3.0.dist-info/entry_points.txt,sha256=x4Y7t6Y0Qev_3fgG-Jv7TrsvVdJty3FnGAdkT8-_5mY,49
|
19
|
+
cachier-3.3.0.dist-info/top_level.txt,sha256=_rW_HiJumDCch67YT-WAgzcyvKg5RiYDMZq9d-0ZpaE,8
|
20
|
+
cachier-3.3.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|