def _merge_a_into_b(a, b):
    'Merge config dictionary a into config dictionary b, clobbering the\n    options in b whenever they are also specified in a.\n    '
    if (type(a) is not edict):
        return
    for (k, v) in a.items():
        if (k not in b):
            raise KeyError('{} is not a valid config key'.format(k))
        old_type = type(b[k])
        if (old_type is not type(v)):
            if isinstance(b[k], np.ndarray):
                v = np.array(v, dtype=b[k].dtype)
            else:
                raise ValueError('Type mismatch ({} vs. {}) for config key: {}'.format(type(b[k]), type(v), k))
        if (type(v) is edict):
            try:
                _merge_a_into_b(a[k], b[k])
            except:
                print('Error under config key: {}'.format(k))
                raise
        else:
            b[k] = v
Merge config dictionary a into config dictionary b, clobbering the
options in b whenever they are also specified in a.
def _merge_a_into_b(a, b):
    'Merge config dictionary a into config dictionary b, clobbering the\n    options in b whenever they are also specified in a.\n    '
    if (type(a) is not edict):
        return
    for (k, v) in a.items():
        if (k not in b):
            raise KeyError('{} is not a valid config key'.format(k))
        old_type = type(b[k])
        if (old_type is not type(v)):
            if isinstance(b[k], np.ndarray):
                v = np.array(v, dtype=b[k].dtype)
            else:
                raise ValueError('Type mismatch ({} vs. {}) for config key: {}'.format(type(b[k]), type(v), k))
        if (type(v) is edict):
            try:
                _merge_a_into_b(a[k], b[k])
            except:
                print('Error under config key: {}'.format(k))
                raise
        else:
            b[k] = v