Commit ae9b4f76 authored by Matias Guijarro's avatar Matias Guijarro
Browse files

common/ added 'deep_update' function

Update values of nested dict of varying depth
parent 6c3e7929
......@@ -606,3 +606,19 @@ class autocomplete_property(property):
def deep_update(source, overrides):
Update a nested dictionary or similar mapping.
Modify ``source`` in place.
Copied from
for key, value in overrides.items():
if isinstance(value, and value:
returned = deep_update(source.get(key, {}), value)
source[key] = returned
source[key] = overrides[key]
return source
......@@ -23,7 +23,7 @@ from bliss.common.event import connect, send, disconnect
from bliss.common.cleanup import error_cleanup, axis as cleanup_axis, capture_exceptions
from bliss.common.greenlet_utils import KillMask
from bliss.common.plot import get_flint, CurvePlot, ImagePlot
from bliss.common.utils import periodic_exec
from bliss.common.utils import periodic_exec, deep_update
from .scan_meta import get_user_scan_meta
from bliss.common.utils import Statistics, Null
from bliss.config.conductor import client
......@@ -961,7 +961,7 @@ class Scan:
# make sure that 'positioners' entry is not updated
nested_dict_update(self._scan_info, tmp_dict)
deep_update(self._scan_info, tmp_dict)
# update scan_info in redis
......@@ -1124,24 +1124,3 @@ class Scan:
gevent.joinall(preset_tasks, raise_error=True)
# there should be something like this in the python standard lib, but I didn't find it...
# ... suggestions welcome
# ... in case we keep our own implementation ... where should it be? in utils?
def nested_dict_update(dict_to_update, newdict):
present_key_value_pairs = [
(key, value) for (key, value) in newdict.items() if key in dict_to_update.keys()
new_key_value_pairs = [
(key, value)
for (key, value) in newdict.items()
if not key in dict_to_update.keys()
for key, new_value in present_key_value_pairs:
if isinstance(new_value, dict):
dict_to_update[key] = nested_dict_update(dict_to_update[key], new_value)
dict_to_update[key] = new_value
return dict_to_update
......@@ -7,8 +7,8 @@
from bliss import setup_globals
from bliss.common.standard import wa, wm, sta, stm
from import repl
from bliss.common.utils import deep_update
repl.ERROR_REPORT.expert_mode = True
......@@ -168,3 +168,30 @@ def test_stm_exception(beacon, capsys):
errmsg = "RuntimeError: Error on motor 'bad': BAD POSITION\n"
assert captured.err[-len(errmsg) :] == errmsg
def test_deep_update():
source = {"hello1": 1}
overrides = {"hello2": 2}
deep_update(source, overrides)
assert source == {"hello1": 1, "hello2": 2}
source = {"hello": "to_override"}
overrides = {"hello": "over"}
deep_update(source, overrides)
assert source == {"hello": "over"}
source = {"hello": {"value": "to_override", "no_change": 1}}
overrides = {"hello": {"value": "over"}}
deep_update(source, overrides)
assert source == {"hello": {"value": "over", "no_change": 1}}
source = {"hello": {"value": "to_override", "no_change": 1}}
overrides = {"hello": {"value": {}}}
deep_update(source, overrides)
assert source == {"hello": {"value": {}, "no_change": 1}}
source = {"hello": {"value": {}, "no_change": 1}}
overrides = {"hello": {"value": 2}}
deep_update(source, overrides)
assert source == {"hello": {"value": 2, "no_change": 1}}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment