Skip to content

Commit 5e51f45

Browse files
authored
match_object() - Do not try to serialize identity functions (#22)
1 parent b6600d2 commit 5e51f45

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

localstack_snapshot/snapshots/prototype.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,21 @@ def _convert_object_to_dict(obj_):
183183
return obj_.value
184184
elif hasattr(obj_, "__dict__"):
185185
# This is an object - let's try to convert it to a dictionary
186-
# A naive approach would be to use the '__dict__' object directly, but that only lists the attributes
186+
# A naive approach would be to use the '__dict__' object directly, but that only lists the attributes.
187187
# In order to also serialize the properties, we use the __dir__() method
188188
# Filtering by everything that is not a method gives us both attributes and properties
189-
# We also (still) skip private attributes/properties, so everything that starts with an underscore
189+
# We also (still) skip private attributes/properties, so everything that starts with an underscore.
190190
return {
191191
k: _convert_object_to_dict(getattr(obj_, k))
192192
for k in obj_.__dir__()
193-
if not k.startswith("_") and type(getattr(obj_, k, "")).__name__ != "method"
193+
if (
194+
# Skip private attributes
195+
not k.startswith("_")
196+
# Skip everything that's not a method
197+
and type(getattr(obj_, k, "")).__name__ != "method"
198+
# Skip everything that refers to itself (identity functions), as that leads to recursion
199+
and getattr(obj_, k) != obj_
200+
)
194201
}
195202
return obj_
196203

tests/test_snapshots.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,21 @@ def __init__(self, name):
137137
sm.match_object("key_a", CustomObject(name="myname"))
138138
sm._assert_all()
139139

140+
def test_match_object_with_identity_function(self):
141+
class CustomObject:
142+
def __init__(self, name):
143+
self.name = name
144+
145+
@property
146+
def me_myself_and_i(self):
147+
# This would lead to a RecursionError, so we cannot snapshot this method
148+
return self
149+
150+
sm = SnapshotSession(scope_key="A", verify=True, base_file_path="", update=False)
151+
sm.recorded_state = {"key_a": {"name": "myname"}}
152+
sm.match_object("key_a", CustomObject(name="myname"))
153+
sm._assert_all()
154+
140155
def test_match_object_change(self):
141156
class CustomObject:
142157
def __init__(self, name):

0 commit comments

Comments
 (0)