Merge & Replace#

from pprint import pprint

from dicfg.reader import ConfigReader
!cat ./configs/config.yml
config_reader = ConfigReader(name="myconfig")
default:
    config_int: 1
    config_string: "fire"
    config_list: [1, 2, 3]
    config_none: None
    config_dict:
        sub_config: "water"

Config values can be merged or replaced with @replace(true|false).#

# primitive config values will always be replaced even when @replace(false) is used.

user_config = {"myconfig": {"default": {"config_int@replace(false)": 2}}}
pprint(config_reader.read(user_config), sort_dicts=False)
{'default': {'config_int': 2,
             'config_string': 'fire',
             'config_list': [1, 2, 3],
             'config_none': 'None',
             'config_dict': {'sub_config': 'water'}}}

Dictionaries will be merged by default (@replace(false)).#

user_config = {"myconfig": {"default": {"config_dict": {"sub_config2": "earth"}}}}
pprint(config_reader.read(user_config), sort_dicts=False)
{'default': {'config_int': 1,
             'config_string': 'fire',
             'config_list': [1, 2, 3],
             'config_none': 'None',
             'config_dict': {'sub_config': 'water', 'sub_config2': 'earth'}}}

Dictionaries can be replaced by @replace(true).#

user_config = {
    "myconfig": {"default": {"config_dict@replace(true)": {"sub_config2": "earth"}}}
}
pprint(config_reader.read(user_config), sort_dicts=False)
{'default': {'config_int': 1,
             'config_string': 'fire',
             'config_list': [1, 2, 3],
             'config_none': 'None',
             'config_dict': {'sub_config2': 'earth'}}}

List will be replaced by default (@replace(true)).#

user_config = {"myconfig": {"default": {"config_list": [2, 4, 6]}}}
pprint(config_reader.read(user_config), sort_dicts=False)
{'default': {'config_int': 1,
             'config_string': 'fire',
             'config_list': [2, 4, 6],
             'config_none': 'None',
             'config_dict': {'sub_config': 'water'}}}

List can be merged with @replace(false).#

user_config = {"myconfig": {"default": {"config_list@replace(false)": [2, 4, 6]}}}
pprint(config_reader.read(user_config), sort_dicts=False)
{'default': {'config_int': 1,
             'config_string': 'fire',
             'config_list': [1, 2, 3, 2, 4, 6],
             'config_none': 'None',
             'config_dict': {'sub_config': 'water'}}}

Updating with type difference will always result in a replace.#

user_config = {"myconfig": {"default": {"config_list": "not a list anymore"}}}
pprint(config_reader.read(user_config), sort_dicts=False)
{'default': {'config_int': 1,
             'config_string': 'fire',
             'config_list': 'not a list anymore',
             'config_none': 'None',
             'config_dict': {'sub_config': 'water'}}}