1. A lot of plugins seem to make a huge effort to keep their configurations up to date.
    Here's a small Python-snippet that matches the loaded config against the expected default config and overwrites parts from config that don't match the default config.

    Code:
    only_check_type = [(list, tuple), (int, float), str, bool]
    def mask_default_cfg(dcfg, cfg):
        # causes changes in cfg to affect dcfg,
        # which is fine since we don't care about the default cfg
        # after masking
        if dcfg is None:
            return dcfg
        if isinstance(dcfg, dict):
            if not isinstance(cfg, dict):
                return dcfg
            for k, v in dcfg.items():
                if k not in cfg:
                    cfg[k] = v
                    continue
                cfg[k] = mask_default_cfg(v, cfg[k])
            return cfg
        for t in only_check_type:
            if isinstance(dcfg, t):
                return cfg if isinstance(cfg, t) else dcfg
        raise TypeError("did not expect type %s in default cfg" % type(dcfg))
    This recursively checks whether the structure of nested dicts match and whether the expected value types match as well.

    Here are some examples of what it does:
    Code:
    dcfg
    {
        "Foo": "Bar"
    }
    cfg
    {}
    result
    {
        "Foo": "Bar"
    }dcfg
    {
        "Foo": "Bar"
    }
    cfg
    {
        "Foo": 1
    }
    result
    {
        "Foo": "Bar"
    }dcfg
    {
        "Foo": {
            "Bar": {
                "Foobar": 3,
                "Barfoo": "a value"
            }
        }
    }
    cfg
    {
        "Foo": {
            "Bar": {
                "Foobar": "a string",
                "Barfoo": "another value"
            }
        }
    }
    result
    {
        "Foo": {
            "Bar": {
                "Foobar": 3,
                "Barfoo": "another value"
            }
        }
    }
    It will only recursively validate dictionaries, not things like lists of dictionaries or nested lists. Only dictionaries have their structure validated, since for dictionaries, it is fairly common for the default config to contain the full structure you can use to automatically match configs, while for lists this can not be guaranteed (the default might be empty).

    Lists and tuples are treated interchangably, as well as floats and ints (floats in the default config may be ints as well in the config).

    Keep in mind that this creates a new type that links together cfg and dcfg, so mutating the resulting type will mutate cfg and dcfg.