Skip to content

Commit 641d6cd

Browse files
committed
test: add tests for falsy value handling in list utils
Signed-off-by: Rishi Jat <rishijat098@gmail.com>
1 parent 519da18 commit 641d6cd

File tree

2 files changed

+58
-7
lines changed

2 files changed

+58
-7
lines changed

tests/trestle/utils/list_utils_test.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,49 @@ def test_deep_update() -> None:
146146
list_utils.deep_update(d, [], {'x': 'y'})
147147
list_utils.deep_update(d, ['foo'], {'x': 'y'})
148148
assert d['foo'] == {'bar': {'a': 'b', 'c': 'd'}, 'x': 'y'}
149+
150+
151+
def test_deep_set_falsy_values() -> None:
152+
"""Test deep_set preserves falsy values that are not None."""
153+
d: dict = {}
154+
list_utils.deep_set(d, ['count'], 0)
155+
assert d['count'] == 0
156+
157+
list_utils.deep_set(d, ['enabled'], False)
158+
assert d['enabled'] is False
159+
160+
list_utils.deep_set(d, ['name'], '')
161+
assert d['name'] == ''
162+
163+
list_utils.deep_set(d, ['items'], [])
164+
assert d['items'] == []
165+
166+
list_utils.deep_set(d, ['meta'], {})
167+
assert d['meta'] == {}
168+
169+
# None should still pop the key
170+
list_utils.deep_set(d, ['count'], None)
171+
assert 'count' not in d
172+
173+
174+
def test_set_or_pop_falsy_values() -> None:
175+
"""Test set_or_pop preserves falsy values that are not None."""
176+
d: dict = {}
177+
178+
list_utils.set_or_pop(d, 'enabled', False)
179+
assert d['enabled'] is False
180+
181+
list_utils.set_or_pop(d, 'name', '')
182+
assert d['name'] == ''
183+
184+
list_utils.set_or_pop(d, 'count', 0)
185+
assert d['count'] == 0
186+
187+
list_utils.set_or_pop(d, 'items', [])
188+
assert d['items'] == []
189+
190+
# None should still remove the key
191+
list_utils.set_or_pop(d, 'key', 'value')
192+
assert d['key'] == 'value'
193+
list_utils.set_or_pop(d, 'key', None)
194+
assert 'key' not in d

trestle/common/list_utils.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,10 @@ def deep_set(dic: Dict[str, Any], path: List[str], value: Any, pop_if_none: bool
144144
for node in path[:-1]:
145145
dic[node] = dic.get(node, {})
146146
dic = dic[node]
147-
if value is not None or not pop_if_none:
148-
dic[path[-1]] = value
147+
if pop_if_none:
148+
set_or_pop(dic, path[-1], value)
149149
else:
150-
dic.pop(path[-1], None)
150+
dic[path[-1]] = value
151151

152152

153153
def deep_get(dic: Dict[str, Any], path: List[str], default: Any = None) -> Any:
@@ -184,8 +184,13 @@ def deep_append(dic: Dict[str, Any], path: List[str], value: Any) -> None:
184184

185185

186186
def set_or_pop(dic: Dict[str, Any], key: str, value: Any) -> None:
187-
"""Set if value is non-empty list or not None otherwise remove."""
188-
if value is not None:
189-
dic[key] = value
190-
else:
187+
"""Set value unless it is None or an empty container."""
188+
if value is None:
191189
dic.pop(key, None)
190+
return
191+
192+
if isinstance(value, (list, dict, set)) and not value:
193+
dic.pop(key, None)
194+
return
195+
196+
dic[key] = value

0 commit comments

Comments
 (0)