Unverified Commit 45a39dc6 authored by Jerry Jiarui XU's avatar Jerry Jiarui XU Committed by GitHub
Browse files

make config merge a into b non-inplace (#254)

parent f7de63fd
...@@ -126,7 +126,7 @@ class Config(object): ...@@ -126,7 +126,7 @@ class Config(object):
raise KeyError('Duplicate key is not allowed among bases') raise KeyError('Duplicate key is not allowed among bases')
base_cfg_dict.update(c) base_cfg_dict.update(c)
Config._merge_a_into_b(cfg_dict, base_cfg_dict) base_cfg_dict = Config._merge_a_into_b(cfg_dict, base_cfg_dict)
cfg_dict = base_cfg_dict cfg_dict = base_cfg_dict
# merge cfg_text # merge cfg_text
...@@ -137,7 +137,10 @@ class Config(object): ...@@ -137,7 +137,10 @@ class Config(object):
@staticmethod @staticmethod
def _merge_a_into_b(a, b): def _merge_a_into_b(a, b):
# merge dict `a` into dict `b`. values in `a` will overwrite `b`. # merge dict `a` into dict `b` (non-inplace). values in `a` will
# overwrite `b`.
# copy first to avoid inplace modification
b = b.copy()
for k, v in a.items(): for k, v in a.items():
if isinstance(v, dict) and k in b and not v.pop(DELETE_KEY, False): if isinstance(v, dict) and k in b and not v.pop(DELETE_KEY, False):
if not isinstance(b[k], dict): if not isinstance(b[k], dict):
...@@ -145,9 +148,10 @@ class Config(object): ...@@ -145,9 +148,10 @@ class Config(object):
f'{k}={v} cannot be inherited from base because {k} ' f'{k}={v} cannot be inherited from base because {k} '
'is a dict in the child config. You may ' 'is a dict in the child config. You may '
f'set `{DELETE_KEY}=True` to ignore the base config') f'set `{DELETE_KEY}=True` to ignore the base config')
Config._merge_a_into_b(v, b[k]) b[k] = Config._merge_a_into_b(v, b[k])
else: else:
b[k] = v b[k] = v
return b
@staticmethod @staticmethod
def fromfile(filename): def fromfile(filename):
...@@ -312,7 +316,8 @@ class Config(object): ...@@ -312,7 +316,8 @@ class Config(object):
d[subkey] = v d[subkey] = v
cfg_dict = super(Config, self).__getattribute__('_cfg_dict') cfg_dict = super(Config, self).__getattribute__('_cfg_dict')
Config._merge_a_into_b(option_cfg_dict, cfg_dict) super(Config, self).__setattr__(
'_cfg_dict', Config._merge_a_into_b(option_cfg_dict, cfg_dict))
class DictAction(Action): class DictAction(Action):
......
item1 = [1, 2]
item2 = {'a': 0}
item3 = True
item4 = 'test'
item_cfg = {'b': 1}
item5 = {'cfg': item_cfg}
item6 = {'cfg': item_cfg}
_base_ = './i_base.py'
item_cfg = {'b': 2}
item6 = {'cfg': item_cfg}
...@@ -120,6 +120,20 @@ def test_merge_delete(): ...@@ -120,6 +120,20 @@ def test_merge_delete():
assert '_delete_' not in cfg.item2 assert '_delete_' not in cfg.item2
def test_merge_intermediate_variable():
cfg_file = osp.join(osp.dirname(__file__), 'data/config/i_child.py')
cfg = Config.fromfile(cfg_file)
# cfg.field
assert cfg.item1 == [1, 2]
assert cfg.item2 == dict(a=0)
assert cfg.item3 is True
assert cfg.item4 == 'test'
assert cfg.item_cfg == dict(b=2)
assert cfg.item5 == dict(cfg=dict(b=1))
assert cfg.item6 == dict(cfg=dict(b=2))
def test_dict(): def test_dict():
cfg_dict = dict(item1=[1, 2], item2=dict(a=0), item3=True, item4='test') cfg_dict = dict(item1=[1, 2], item2=dict(a=0), item3=True, item4='test')
......
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