summary refs log tree commit diff
diff options
context:
space:
mode:
authorOlivier Wilkinson (reivilibre) <oliverw@matrix.org>2023-11-16 15:26:17 +0000
committerOlivier Wilkinson (reivilibre) <oliverw@matrix.org>2023-11-17 12:03:56 +0000
commit8b7463957fa6642c5a6fd2a6685b00cc7acfd35c (patch)
tree3d2a0d06d2d5ba02b4e10bc28599ccdff6b9e075
parentTweak comments (diff)
downloadsynapse-8b7463957fa6642c5a6fd2a6685b00cc7acfd35c.tar.xz
Add `merge_into`
-rwxr-xr-xdocker/configure_workers_and_start.py25
1 files changed, 25 insertions, 0 deletions
diff --git a/docker/configure_workers_and_start.py b/docker/configure_workers_and_start.py
index 98958d52af..5c15b4b9fd 100755
--- a/docker/configure_workers_and_start.py
+++ b/docker/configure_workers_and_start.py
@@ -283,6 +283,31 @@ def flush_buffers() -> None:
     sys.stderr.flush()
 
 
+def merge_into(dest: Any, new: Any) -> None:
+    """
+    Merges `new` into `dest` with the following rules:
+
+    - dicts: values with the same key will be merged recursively
+    - lists: `new` will be appended to `dest`
+    - primitives: they will be checked for equality and inequality will result
+        in a ValueError
+
+    It is an error for `dest` and `new` to be of different types.
+    """
+    if isinstance(dest, dict) and isinstance(new, dict):
+        for k, v in new.items():
+            if k in dest:
+                merge_into(dest[k], v)
+            else:
+                dest[k] = v
+    elif isinstance(dest, list) and isinstance(new, list):
+        dest.extend(new)
+    elif type(dest) != type(new):
+        raise TypeError(f"Cannot merge {type(dest).__name__} and {type(new).__name__}")
+    elif dest != new:
+        raise ValueError(f"Cannot merge primitive values: {dest!r} != {new!r}")
+
+
 def convert(src: str, dst: str, **template_vars: object) -> None:
     """Generate a file from a template