😏
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
# Deep merge contract
|
||||
|
||||
`merge_settings(base, overlay)` returns a fresh mapping. Nested mappings merge recursively; overlay scalars replace base values; no input or nested output may be mutated or aliased.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
|
||||
def merge_settings(base: Mapping[str, Any], overlay: Mapping[str, Any]) -> dict[str, Any]:
|
||||
result = dict(base)
|
||||
for key, value in overlay.items():
|
||||
if isinstance(value, Mapping) and isinstance(result.get(key), Mapping):
|
||||
result[key].update(value)
|
||||
else:
|
||||
result[key] = value
|
||||
return result
|
||||
@@ -0,0 +1,23 @@
|
||||
import unittest
|
||||
|
||||
from settings import merge_settings
|
||||
|
||||
|
||||
class MergeSettingsTests(unittest.TestCase):
|
||||
def test_recursive_merge(self):
|
||||
self.assertEqual(
|
||||
merge_settings({"s": {"host": "x", "port": 80}}, {"s": {"port": 443}}),
|
||||
{"s": {"host": "x", "port": 443}},
|
||||
)
|
||||
|
||||
def test_inputs_and_outputs_do_not_alias(self):
|
||||
base = {"s": {"host": "x"}, "flags": {"safe": True}}
|
||||
overlay = {"s": {"port": 443}}
|
||||
merged = merge_settings(base, overlay)
|
||||
merged["s"]["host"] = "changed"
|
||||
merged["flags"]["safe"] = False
|
||||
self.assertEqual(base, {"s": {"host": "x"}, "flags": {"safe": True}})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user