Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Benoit Rousselle
bliss
Commits
ae9b4f76
Commit
ae9b4f76
authored
May 17, 2019
by
Matias Guijarro
Browse files
common/utils.py: added 'deep_update' function
Update values of nested dict of varying depth
parent
6c3e7929
Changes
3
Hide whitespace changes
Inline
Side-by-side
bliss/common/utils.py
View file @
ae9b4f76
...
...
@@ -606,3 +606,19 @@ class autocomplete_property(property):
"""
pass
def
deep_update
(
source
,
overrides
):
"""
Update a nested dictionary or similar mapping.
Modify ``source`` in place.
Copied from https://stackoverflow.com/questions/3232943/update-value-of-a-nested-dictionary-of-varying-depth/32357112#32357112
"""
for
key
,
value
in
overrides
.
items
():
if
isinstance
(
value
,
collections
.
abc
.
Mapping
)
and
value
:
returned
=
deep_update
(
source
.
get
(
key
,
{}),
value
)
source
[
key
]
=
returned
else
:
source
[
key
]
=
overrides
[
key
]
return
source
bliss/scanning/scan.py
View file @
ae9b4f76
...
...
@@ -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
tmp_dict
[
"instrument"
].
pop
(
"positioners"
)
tmp_dict
[
"instrument"
].
pop
(
"positioners_dial"
)
nested_dict
_update
(
self
.
_scan_info
,
tmp_dict
)
deep
_update
(
self
.
_scan_info
,
tmp_dict
)
# update scan_info in redis
self
.
node
.
_info
.
update
(
self
.
scan_info
)
...
...
@@ -1124,24 +1124,3 @@ class Scan:
gevent
.
joinall
(
preset_tasks
,
raise_error
=
True
)
finally
:
gevent
.
killall
(
preset_tasks
)
# 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
)
else
:
dict_to_update
[
key
]
=
new_value
dict_to_update
.
update
(
dict
(
new_key_value_pairs
))
return
dict_to_update
tests/test_standard.py
View file @
ae9b4f76
...
...
@@ -7,8 +7,8 @@
from
bliss
import
setup_globals
from
bliss.common.standard
import
wa
,
wm
,
sta
,
stm
from
bliss.shell.cli
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
}}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment