fix: freeze evidence metadata lists as lists (preserve JSON shape)

This commit is contained in:
2026-08-13 19:30:40 +02:00
parent f31b1e61ac
commit f9d23d2361
2 changed files with 22 additions and 2 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ def test_normalize_utf8_bom_newlines_unicode_and_frontmatter():
assert document.content == "Café\nBody\n"
assert document.title == "Café"
assert document.metadata["frontmatter"] == {"tags": ("uno", "due"), "title": "Café"}
assert document.metadata["frontmatter"] == {"tags": ["uno", "due"], "title": "Café"}
assert document.metadata["source"] == {"owner": "docs"}
assert document.metadata["acquisition"] == {"transport": "http"}
assert document.source_uri == "https://host/guide.md"
+21 -1
View File
@@ -26,6 +26,26 @@ class FrozenDict(dict):
update = _immutable
class FrozenList(list):
"""A JSON-serializable list whose mutation operations are disabled."""
def _immutable(self, *args, **kwargs):
raise TypeError("frozen JSON metadata cannot be mutated")
__delitem__ = _immutable
__iadd__ = _immutable
__imul__ = _immutable
__setitem__ = _immutable
append = _immutable
clear = _immutable
extend = _immutable
insert = _immutable
pop = _immutable
remove = _immutable
reverse = _immutable
sort = _immutable
_CAMEL_BOUNDARY = re.compile(r"(?<=[a-z0-9])(?=[A-Z])")
_SEPARATORS = re.compile(r"[^a-z0-9]+")
_NAMESPACED_VALUE = re.compile(r"^[a-z][a-z0-9_-]*:[A-Za-z0-9._:-]+$")
@@ -72,7 +92,7 @@ def freeze_json(value):
if isinstance(value, Mapping):
return FrozenDict({str(key): freeze_json(child) for key, child in value.items()})
if isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)):
return tuple(freeze_json(child) for child in value)
return FrozenList(freeze_json(child) for child in value)
return value