Skip to content

Commit c5394f5

Browse files
committed
ISSUE-1503: ISSUE-1503: ISSUE-1503: fix: add Mapping abc and missing methods to DictWrapper
ISSUE-1503: Add DictWrapper Mapping abc tests ISSUE-1503: add StreamRecord tests
1 parent 9e54eb8 commit c5394f5

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

aws_lambda_powertools/utilities/data_classes/common.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import base64
22
import json
3-
from typing import Any, Dict, Optional
3+
from typing import Any, Dict, Iterator, Mapping, Optional
44

55

6-
class DictWrapper:
6+
class DictWrapper(Mapping):
77
"""Provides a single read only access to a wrapper dict"""
88

99
def __init__(self, data: Dict[str, Any]):
@@ -19,6 +19,12 @@ def __eq__(self, other: Any) -> bool:
1919

2020
return self._data == other._data
2121

22+
def __iter__(self) -> Iterator:
23+
return iter(self._data)
24+
25+
def __len__(self) -> int:
26+
return len(self._data)
27+
2228
def get(self, key: str, default: Optional[Any] = None) -> Optional[Any]:
2329
return self._data.get(key, default)
2430

aws_lambda_powertools/utilities/data_classes/dynamo_db_stream_event.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,10 @@ def approximate_creation_date_time(self) -> Optional[int]:
182182
item = self.get("ApproximateCreationDateTime")
183183
return None if item is None else int(item)
184184

185+
# This override breaks the Mapping protocol of DictWrapper, it's left here for backwards compatibility with
186+
# a 'type: ignore' comment. This is currently the only subclass of DictWrapper that breaks this protocol.
185187
@property
186-
def keys(self) -> Optional[Dict[str, AttributeValue]]:
188+
def keys(self) -> Optional[Dict[str, AttributeValue]]: # type: ignore
187189
"""The primary key attribute(s) for the DynamoDB item that was modified."""
188190
return _attribute_value_dict(self._data, "Keys")
189191

tests/functional/test_data_classes.py

+31
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
AttributeValueType,
7575
DynamoDBRecordEventName,
7676
DynamoDBStreamEvent,
77+
StreamRecord,
7778
StreamViewType,
7879
)
7980
from aws_lambda_powertools.utilities.data_classes.event_source import event_source
@@ -101,6 +102,19 @@ def message(self) -> str:
101102
assert DataClassSample(data1).raw_event is data1
102103

103104

105+
def test_dict_wrapper_imlements_mapping():
106+
class DataClassSample(DictWrapper):
107+
pass
108+
109+
data = {"message": "foo1"}
110+
dcs = DataClassSample(data)
111+
assert len(dcs) == len(data)
112+
assert list(dcs) == list(data)
113+
assert dcs.keys() == data.keys()
114+
assert list(dcs.values()) == list(data.values())
115+
assert dcs.items() == data.items()
116+
117+
104118
def test_cloud_watch_dashboard_event():
105119
event = CloudWatchDashboardCustomWidgetEvent(load_event("cloudWatchDashboardEvent.json"))
106120
assert event.describe is False
@@ -617,6 +631,23 @@ def test_dynamo_attribute_value_type_error():
617631
print(attribute_value.get_type)
618632

619633

634+
def test_stream_record_keys_with_valid_keys():
635+
attribute_value = {"Foo": "Bar"}
636+
sr = StreamRecord({"Keys": {"Key1": attribute_value}})
637+
assert sr.keys == {"Key1": AttributeValue(attribute_value)}
638+
639+
640+
def test_stream_record_keys_with_no_keys():
641+
sr = StreamRecord({})
642+
assert sr.keys is None
643+
644+
645+
def test_stream_record_keys_overrides_dict_wrapper_keys():
646+
data = {"Keys": {"key1": {"attr1": "value1"}}}
647+
sr = StreamRecord(data)
648+
assert sr.keys != data.keys()
649+
650+
620651
def test_event_bridge_event():
621652
event = EventBridgeEvent(load_event("eventBridgeEvent.json"))
622653

0 commit comments

Comments
 (0)