From 88e017337a1cda60d455cb763f7354071804e6b3 Mon Sep 17 00:00:00 2001 From: Jiazhen Wang <47851024+teamwong111@users.noreply.github.com> Date: Tue, 14 Dec 2021 13:17:57 +0800 Subject: [PATCH] [Fix] fix config type inconsistency (#1575) * [Fix] fix config type inconsistency * [Fix] Fix unit test --- mmcv/utils/config.py | 23 +++++++++++++---------- tests/data/config/delete.py | 3 ++- tests/test_utils/test_config.py | 10 +++++++--- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/mmcv/utils/config.py b/mmcv/utils/config.py index 5b9dfbb5a..b5587e407 100644 --- a/mmcv/utils/config.py +++ b/mmcv/utils/config.py @@ -310,16 +310,19 @@ class Config: if len(b) <= k: raise KeyError(f'Index {k} exceeds the length of list {b}') b[k] = Config._merge_a_into_b(v, b[k], allow_list_keys) - elif isinstance(v, - dict) and k in b and not v.pop(DELETE_KEY, False): - allowed_types = (dict, list) if allow_list_keys else dict - if not isinstance(b[k], allowed_types): - raise TypeError( - f'{k}={v} in child config cannot inherit from base ' - f'because {k} is a dict in the child config but is of ' - f'type {type(b[k])} in base config. You may set ' - f'`{DELETE_KEY}=True` to ignore the base config') - b[k] = Config._merge_a_into_b(v, b[k], allow_list_keys) + elif isinstance(v, dict): + if k in b and not v.pop(DELETE_KEY, False): + allowed_types = (dict, list) if allow_list_keys else dict + if not isinstance(b[k], allowed_types): + raise TypeError( + f'{k}={v} in child config cannot inherit from ' + f'base because {k} is a dict in the child config ' + f'but is of type {type(b[k])} in base config. ' + f'You may set `{DELETE_KEY}=True` to ignore the ' + f'base config.') + b[k] = Config._merge_a_into_b(v, b[k], allow_list_keys) + else: + b[k] = ConfigDict(v) else: b[k] = v return b diff --git a/tests/data/config/delete.py b/tests/data/config/delete.py index 2b055c84a..668400c13 100644 --- a/tests/data/config/delete.py +++ b/tests/data/config/delete.py @@ -1,2 +1,3 @@ _base_ = './base.py' -item2 = {'b': 0, '_delete_': True} +item1 = {'a': 0, '_delete_': True} +item2 = {'b': 0} diff --git a/tests/test_utils/test_config.py b/tests/test_utils/test_config.py index 89520de7f..08570ce24 100644 --- a/tests/test_utils/test_config.py +++ b/tests/test_utils/test_config.py @@ -10,7 +10,7 @@ from pathlib import Path import pytest import yaml -from mmcv import Config, DictAction, dump, load +from mmcv import Config, ConfigDict, DictAction, dump, load data_path = osp.join(osp.dirname(osp.dirname(__file__)), 'data') @@ -347,12 +347,16 @@ def test_merge_delete(): cfg_file = osp.join(data_path, 'config/delete.py') cfg = Config.fromfile(cfg_file) # cfg.field - assert cfg.item1 == [1, 2] - assert cfg.item2 == dict(b=0) + assert cfg.item1 == dict(a=0) + assert cfg.item2 == dict(a=0, b=0) assert cfg.item3 is True assert cfg.item4 == 'test' assert '_delete_' not in cfg.item2 + # related issue: https://github.com/open-mmlab/mmcv/issues/1570 + assert type(cfg.item1) == ConfigDict + assert type(cfg.item2) == ConfigDict + def test_merge_intermediate_variable():