From 617b1ff1f9ba53ac966aa169d677e2f3cf0f4919 Mon Sep 17 00:00:00 2001 From: Sarbajit Sengupta Date: Sat, 31 Oct 2026 23:48:16 +0530 Subject: [PATCH] Preserve shared throttle buckets across decorator recreation --- diskcache/recipes.py | 2 +- tests/test_recipes.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/diskcache/recipes.py b/diskcache/recipes.py index babb68f..3404e6f 100644 --- a/diskcache/recipes.py +++ b/diskcache/recipes.py @@ -285,7 +285,7 @@ def decorator(func): rate = count / float(seconds) key = full_name(func) if name is None else name now = time_func() - cache.set(key, (now, count), expire=expire, tag=tag, retry=True) + cache.add(key, (now, count), expire=expire, tag=tag, retry=True) @functools.wraps(func) def wrapper(*args, **kwargs): diff --git a/tests/test_recipes.py b/tests/test_recipes.py index ae74459..bb913d9 100644 --- a/tests/test_recipes.py +++ b/tests/test_recipes.py @@ -28,6 +28,40 @@ def test_averager(cache): assert nums.pop() == 9.5 +@pytest.mark.parametrize('separate_connection', [False, True]) +def test_throttle_recreation_preserves_bucket(cache, separate_connection): + clock = [0.0] + delays = [] + + def sleep(delay): + delays.append(delay) + clock[0] += delay + + def decorate(connection): + return dc.throttle( + connection, + 1, + 10, + name='shared-api-limit', + time_func=lambda: clock[0], + sleep_func=sleep, + )(lambda: 'result') + + first = decorate(cache) + assert first() == 'result' + assert cache['shared-api-limit'] == (0.0, 0.0) + + connection = dc.Cache(cache.directory) if separate_connection else cache + try: + second = decorate(connection) + assert cache['shared-api-limit'] == (0.0, 0.0) + assert second() == 'result' + assert delays == [10.0] + finally: + if separate_connection: + connection.close() + + def test_lock(cache): state = {'num': 0} lock = dc.Lock(cache, 'demo')