clan_lib: init flatten_data_structured

Avoids ambiguity issues with keys that contain dots or other separators.
This commit is contained in:
Johannes Kirschbauer
2025-09-19 17:30:52 +02:00
parent 78634d0165
commit 4ec3043a4e
2 changed files with 85 additions and 1 deletions

View File

@@ -3,6 +3,26 @@ from typing import Any
from clan_lib.persist.util import flatten_data, list_difference from clan_lib.persist.util import flatten_data, list_difference
def flatten_data_structured(data: dict, parent_path: tuple = ()) -> dict:
"""Flatten using tuple keys instead of string concatenation
Avoids ambiguity issues with keys that contain dots or other separators.
"""
flattened = {}
for key, value in data.items():
current_path = (*parent_path, key)
if isinstance(value, dict):
if value:
flattened.update(flatten_data_structured(value, current_path))
else:
flattened[current_path] = {}
else:
flattened[current_path] = value
return flattened
def calculate_static_data( def calculate_static_data(
all_values: dict[str, Any], persisted: dict[str, Any] all_values: dict[str, Any], persisted: dict[str, Any]
) -> dict[str, Any]: ) -> dict[str, Any]:

View File

@@ -1,4 +1,68 @@
from clan_lib.persist.static_data import calculate_static_data from clan_lib.persist.static_data import calculate_static_data, flatten_data_structured
def test_flatten_data_structured() -> None:
data = {
"name": "example",
"settings": {
"optionA": True,
"optionB": {
"subOption1": 10,
"subOption2": 20,
},
"emptyDict": {},
},
"listSetting": [1, 2, 3],
}
expected_flat = {
("name",): "example",
("settings", "optionA"): True,
("settings", "optionB", "subOption1"): 10,
("settings", "optionB", "subOption2"): 20,
("settings", "emptyDict"): {},
("listSetting",): [1, 2, 3],
}
flattened = flatten_data_structured(data)
assert flattened == expected_flat
def test_flatten_data_structured_empty() -> None:
data: dict = {}
expected_flat: dict = {}
flattened = flatten_data_structured(data)
assert flattened == expected_flat
def test_flatten_data_structured_nested_empty() -> None:
data: dict = {
"level1": {
"level2": {
"level3": {},
},
},
}
expected_flat: dict = {
("level1", "level2", "level3"): {},
}
flattened = flatten_data_structured(data)
assert flattened == expected_flat
def test_flatten_data_dot_in_keys() -> None:
data = {
"key.foo": "value1",
"key": {
"foo": "value2",
},
}
expected_flat = {
("key.foo",): "value1",
("key", "foo"): "value2",
}
flattened = flatten_data_structured(data)
assert flattened == expected_flat
def test_calculate_static_data_basic() -> None: def test_calculate_static_data_basic() -> None: