Skip to content

Commit 4eaffd9

Browse files
author
Michael Brewer
committed
chore: Revert to original fix
1 parent 608660e commit 4eaffd9

File tree

3 files changed

+56
-44
lines changed

3 files changed

+56
-44
lines changed

Diff for: aws_lambda_powertools/shared/cache_dict.py

+18-19
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
11
from collections import OrderedDict
22

33

4-
class LRUDict:
4+
class LRUDict(OrderedDict):
55
"""
66
Cache implementation based on ordered dict with a maximum number of items. Last accessed item will be evicted
7-
first, unless the item is None which will be evicted first. Currently used only by idempotency utility.
7+
first. Currently used by idempotency utility.
88
"""
99

1010
def __init__(self, max_items=1024, *args, **kwargs):
1111
self.max_items = max_items
12-
self._cache = OrderedDict(*args, **kwargs)
12+
super().__init__(*args, **kwargs)
1313

14-
def __getitem__(self, key: str):
15-
value = self._cache.__getitem__(key)
16-
if value:
17-
self._cache.move_to_end(key)
14+
def __getitem__(self, key):
15+
value = super().__getitem__(key)
16+
self.move_to_end(key)
1817
return value
1918

20-
def __setitem__(self, key: str, value):
21-
self._cache.__setitem__(key, value)
22-
if key in self._cache:
23-
self._cache.move_to_end(key, last=value is not None)
24-
if len(self._cache) > self.max_items:
25-
oldest = next(iter(self._cache))
26-
del self._cache[oldest]
19+
def __setitem__(self, key, value):
20+
if key in self:
21+
self.move_to_end(key)
22+
super().__setitem__(key, value)
23+
if len(self) > self.max_items:
24+
oldest = next(iter(self))
25+
del self[oldest]
2726

28-
def get(self, key: str):
29-
value = self._cache.get(key)
30-
if value:
31-
self._cache.move_to_end(key)
32-
return value
27+
def get(self, key, *args, **kwargs):
28+
item = super(LRUDict, self).get(key, *args, **kwargs)
29+
if item:
30+
self.move_to_end(key=key)
31+
return item

Diff for: aws_lambda_powertools/utilities/idempotency/persistence/base.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ def _retrieve_from_cache(self, idempotency_key: str):
272272
def _delete_from_cache(self, idempotency_key: str):
273273
if not self.use_local_cache:
274274
return
275-
self._cache[idempotency_key] = None
275+
if idempotency_key in self._cache:
276+
del self._cache[idempotency_key]
276277

277278
def save_success(self, event: Dict[str, Any], result: dict) -> None:
278279
"""

Diff for: tests/unit/test_lru_cache.py

+36-24
Original file line numberDiff line numberDiff line change
@@ -9,60 +9,72 @@
99

1010

1111
@pytest.fixture
12-
def populated_cache() -> LRUDict:
12+
def populated_cache():
1313
cache_dict = LRUDict(max_items=MAX_CACHE_ITEMS, **{f"key_{i}": f"val_{i}" for i in range(0, PREFILL_CACHE_ITEMS)})
1414
return cache_dict
1515

1616

17-
def test_cache_order_init(populated_cache: LRUDict):
18-
first_item = list(populated_cache._cache)[0]
19-
last_item = list(populated_cache._cache)[-1]
17+
def test_cache_order_init(populated_cache):
18+
first_item = list(populated_cache)[0]
19+
last_item = list(populated_cache)[-1]
2020

2121
assert first_item == "key_0"
2222
assert last_item == f"key_{MAX_CACHE_ITEMS - 1}"
2323

2424

25-
def test_cache_order_getitem(populated_cache: LRUDict):
25+
def test_cache_order_getitem(populated_cache):
2626
random_value = random.randrange(0, MAX_CACHE_ITEMS)
2727
_ = populated_cache[f"key_{random_value}"]
2828

29-
last_item = list(populated_cache._cache)[-1]
29+
last_item = list(populated_cache)[-1]
3030

3131
assert last_item == f"key_{random_value}"
3232

3333

34-
def test_cache_order_get(populated_cache: LRUDict):
34+
def test_cache_order_get(populated_cache):
3535
random_value = random.randrange(0, MAX_CACHE_ITEMS)
3636
_ = populated_cache.get(f"key_{random_value}")
3737

38-
last_item = list(populated_cache._cache)[-1]
38+
last_item = list(populated_cache)[-1]
3939

4040
assert last_item == f"key_{random_value}"
4141

4242

43-
def test_cache_evict_over_max_items(populated_cache: LRUDict):
44-
assert "key_0" in populated_cache._cache
45-
assert len(populated_cache._cache) == MAX_CACHE_ITEMS
43+
def test_cache_evict_over_max_items(populated_cache):
44+
assert "key_0" in populated_cache
45+
assert len(populated_cache) == MAX_CACHE_ITEMS
4646
populated_cache["new_item"] = "new_value"
47-
assert len(populated_cache._cache) == MAX_CACHE_ITEMS
48-
assert "key_0" not in populated_cache._cache
49-
assert "key_1" in populated_cache._cache
47+
assert len(populated_cache) == MAX_CACHE_ITEMS
48+
assert "key_0" not in populated_cache
49+
assert "key_1" in populated_cache
5050

5151

52-
def test_setitem_moves_to_end(populated_cache: LRUDict):
52+
def test_setitem_moves_to_end(populated_cache):
5353
random_value = random.randrange(0, MAX_CACHE_ITEMS)
5454
populated_cache[f"key_{random_value}"] = f"new_val_{random_value}"
55-
last_item = list(populated_cache._cache)[-1]
55+
last_item = list(populated_cache)[-1]
5656

5757
assert last_item == f"key_{random_value}"
5858
assert populated_cache[f"key_{random_value}"] == f"new_val_{random_value}"
5959

6060

61-
def test_setitem_none_not_moved(populated_cache: LRUDict):
62-
populated_cache["value_is_none"] = None
63-
64-
first_item = list(populated_cache._cache)[0]
65-
last_item = list(populated_cache._cache)[-1]
66-
67-
assert first_item == "key_0"
68-
assert last_item == f"key_{MAX_CACHE_ITEMS - 1}"
61+
def test_lru_pop_failing():
62+
cache = LRUDict()
63+
key = "test"
64+
cache[key] = "value"
65+
try:
66+
cache.pop(key, None)
67+
pytest.fail("GitHub #300: LRUDict pop bug has been fixed :)")
68+
except KeyError as e:
69+
assert e.args[0] == key
70+
71+
72+
def test_lru_del():
73+
cache = LRUDict()
74+
key = "test"
75+
cache[key] = "value"
76+
assert len(cache) == 1
77+
if key in cache:
78+
del cache[key]
79+
assert key not in cache
80+
assert len(cache) == 0

0 commit comments

Comments
 (0)