Skip to content

Commit 76966a0

Browse files
author
Joel Collins
committed
Changed rupdate to merge
1 parent 696d5aa commit 76966a0

File tree

5 files changed

+31
-27
lines changed

5 files changed

+31
-27
lines changed

labthings/core/utilities.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import operator
44
import sys
55
import os
6+
import copy
67
from functools import reduce
78

89
PY3 = sys.version_info > (3,)
@@ -39,20 +40,21 @@ def get_summary(obj):
3940
return get_docstring(obj, remove_newlines=False).partition("\n")[0].strip()
4041

4142

42-
def rupdate(destination_dict, update_dict):
43+
def merge(first: dict, second: dict):
4344
"""Recursively update a dictionary
4445
4546
This will take an "update_dictionary",
4647
and recursively merge it with "destination_dict".
4748
4849
Args:
49-
destination_dict (dict): Original dictionary
50-
update_dict (dict): New data dictionary
50+
first (dict): Original dictionary
51+
second (dict): New data dictionary
5152
5253
Returns:
5354
dict: Merged dictionary
5455
"""
55-
for k, v in update_dict.items():
56+
destination_dict = copy.deepcopy(first)
57+
for k, v in second.items():
5658
# Merge lists if they're present in both objects
5759
if isinstance(v, list):
5860
# If key is missing from destination, create the list
@@ -68,7 +70,7 @@ def rupdate(destination_dict, update_dict):
6870
elif isinstance(v, collections.abc.Mapping):
6971
if k not in destination_dict:
7072
destination_dict[k] = {}
71-
destination_dict[k] = rupdate(destination_dict.get(k, {}), v)
73+
destination_dict[k] = merge(destination_dict.get(k, {}), v)
7274
# If not a list or dictionary, overwrite old value with new value
7375
else:
7476
destination_dict[k] = v

labthings/server/decorators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from .utilities import unpack
1717

1818
from labthings.core.tasks.pool import TaskThread
19-
from labthings.core.utilities import rupdate
19+
from labthings.core.utilities import merge
2020

2121
import logging
2222

@@ -304,7 +304,7 @@ def __init__(self, code, description=None, mimetype=None, **kwargs):
304304
}
305305

306306
if self.mimetype:
307-
rupdate(
307+
self.response_dict = merge(
308308
self.response_dict,
309309
{
310310
"responses": {self.code: {"content": {self.mimetype: {}}}},

labthings/server/spec/apispec.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from ..view import View
22
from apispec import APISpec
33

4-
from ...core.utilities import get_docstring, get_summary, rupdate
4+
from ...core.utilities import get_docstring, get_summary, merge
55
from .paths import rule_to_path, rule_to_params
66
from .utilities import convert_schema, update_spec
77

@@ -38,7 +38,7 @@ def rule_to_apispec_path(rule: Rule, view: View, spec: APISpec):
3838

3939
# Add extra parameters
4040
# build_spec(view) guarantees view.__apispec__ exists
41-
rupdate(params, view.__apispec__)
41+
params = merge(params, view.__apispec__)
4242

4343
return params
4444

@@ -64,7 +64,7 @@ def view_to_apispec_operations(view: View, spec: APISpec):
6464
# Populate missing spec parameters
6565
build_spec(method_function, inherit_from=view)
6666

67-
rupdate(
67+
ops[method] = merge(
6868
ops[method],
6969
{
7070
"description": getattr(method_function, "__apispec__").get(
@@ -75,7 +75,9 @@ def view_to_apispec_operations(view: View, spec: APISpec):
7575
},
7676
)
7777

78-
rupdate(ops[method], method_to_apispec_operation(method_function, spec))
78+
ops[method] = merge(
79+
ops[method], method_to_apispec_operation(method_function, spec)
80+
)
7981

8082
return ops
8183

@@ -97,7 +99,7 @@ def method_to_apispec_operation(method: callable, spec: APISpec):
9799

98100
op = {}
99101
if "_params" in apispec:
100-
rupdate(
102+
op = merge(
101103
op,
102104
{
103105
"requestBody": {
@@ -112,7 +114,7 @@ def method_to_apispec_operation(method: callable, spec: APISpec):
112114

113115
if "_schema" in apispec:
114116
for code, schema in apispec.get("_schema", {}).items():
115-
rupdate(
117+
op = merge(
116118
op,
117119
{
118120
"responses": {
@@ -129,7 +131,7 @@ def method_to_apispec_operation(method: callable, spec: APISpec):
129131
)
130132
else:
131133
# If no explicit responses are known, populate with defaults
132-
rupdate(
134+
op = merge(
133135
op,
134136
{
135137
"responses": {
@@ -141,7 +143,7 @@ def method_to_apispec_operation(method: callable, spec: APISpec):
141143
# Bung in any extra swagger fields supplied
142144
for key, val in apispec.items():
143145
if key not in ["_params", "_schema"]:
144-
rupdate(op, {key: val})
146+
op = merge(op, {key: val})
145147

146148
return op
147149

labthings/server/spec/utilities.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from apispec import APISpec
22
from apispec.ext.marshmallow import MarshmallowPlugin
33

4-
from ...core.utilities import rupdate
4+
from ...core.utilities import merge
55

66
from ..fields import Field
77
from marshmallow import Schema as BaseSchema
@@ -17,7 +17,7 @@ def update_spec(obj, spec: dict):
1717
spec (dict): Dictionary of API spec data to add
1818
"""
1919
obj.__apispec__ = obj.__dict__.get("__apispec__", {})
20-
rupdate(obj.__apispec__, spec)
20+
obj.__apispec__ = merge(obj.__apispec__, spec)
2121
return obj.__apispec__ or {}
2222

2323

tests/test_core_utilities.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,51 +47,51 @@ def test_get_summary(example_class):
4747
assert utilities.get_summary(example_class.class_method_no_docstring) == ""
4848

4949

50-
def test_rupdate_granular():
50+
def test_merge_granular():
5151
# Update string value
5252
s1 = {"a": "String"}
5353
s2 = {"a": "String 2"}
54-
assert utilities.rupdate(s1, s2) == s2
54+
assert utilities.merge(s1, s2) == s2
5555

5656
# Update int value
5757
i1 = {"b": 5}
5858
i2 = {"b": 50}
59-
assert utilities.rupdate(i1, i2) == i2
59+
assert utilities.merge(i1, i2) == i2
6060

6161
# Update list elements
6262
l1 = {"c": []}
6363
l2 = {"c": [1, 2, 3, 4]}
64-
assert utilities.rupdate(l1, l2) == l2
64+
assert utilities.merge(l1, l2) == l2
6565

6666
# Extend list elements
6767
l1 = {"c": [1, 2, 3]}
6868
l2 = {"c": [4, 5, 6]}
69-
assert utilities.rupdate(l1, l2)["c"] == [1, 2, 3, 4, 5, 6]
69+
assert utilities.merge(l1, l2)["c"] == [1, 2, 3, 4, 5, 6]
7070

7171
# Merge dictionaries
7272
d1 = {"d": {"a": "String", "b": 5, "c": []}}
7373
d2 = {"d": {"a": "String 2", "b": 50, "c": [1, 2, 3, 4, 5]}}
74-
assert utilities.rupdate(d1, d2) == d2
74+
assert utilities.merge(d1, d2) == d2
7575

7676
# Replace value with list
7777
ml1 = {"k": True}
7878
ml2 = {"k": [1, 2, 3]}
79-
assert utilities.rupdate(ml1, ml2) == ml2
79+
assert utilities.merge(ml1, ml2) == ml2
8080

8181
# Create missing value
8282
ms1 = {}
8383
ms2 = {"k": "v"}
84-
assert utilities.rupdate(ms1, ms2) == ms2
84+
assert utilities.merge(ms1, ms2) == ms2
8585

8686
# Create missing list
8787
ml1 = {}
8888
ml2 = {"k": [1, 2, 3]}
89-
assert utilities.rupdate(ml1, ml2) == ml2
89+
assert utilities.merge(ml1, ml2) == ml2
9090

9191
# Create missing dictionary
9292
md1 = {}
9393
md2 = {"d": {"a": "String 2", "b": 50, "c": [1, 2, 3, 4, 5]}}
94-
assert utilities.rupdate(md1, md2) == md2
94+
assert utilities.merge(md1, md2) == md2
9595

9696

9797
def test_rapply():

0 commit comments

Comments
 (0)