turn a ConfigParser into a nested dict
    
    because ConfigParser objects are dumb.
513026
def cfg2dict(cfg):
    
    d = {}
    for section in cfg.sections():
        d[section] = dict(cfg.items(section))
    return d
363903
def dump(self) -> dict:
        
        d = {}
        for item in self.__dict__:
            if item in ['parsed', 'dump', 'parse_data', 'iter_list', 'safe_load']:
                continue
            if isinstance(self.__dict__[item], ConfigKey):
                d[item] = self.__dict__[item].dump()
            elif isinstance(self.__dict__[item], list):
                d[item] = self.iter_list_dump(self.__dict__[item])
            else:
                d[item] = self.__dict__[item]
        return d
450555
def normalize_dict(dictionary, **kwargs):
    
    result = {}
    if isinstance(dictionary, dict):
        keys = list(dictionary.keys())
        for key in keys:
            result[normalizer(key, **kwargs)] = normalize_dict(dictionary.get(key), **kwargs)
    else:
        result = dictionary
    return result
499525
def to_yaml(cls, config, compact=False, indent=2, level=0):
        
        lines = ""
        if isinstance(config, ConfigTree):
            if len(config) > 0:
                if level > 0:
                    lines += '\n'
                bet_lines = []
                for key, item in config.items():
                    bet_lines.append('{indent}{key}: {value}'.format(
                        indent=''.rjust(level * indent, ' '),
                        key=key.strip('"'),  # for dotted keys enclosed with "" to not be interpreted as nested key,
                        value=cls.to_yaml(item, compact, indent, level + 1))
                    )
                lines += '\n'.join(bet_lines)
        elif isinstance(config, list):
            config_list = [line for line in config if line is not None]
            if len(config_list) == 0:
                lines += '[]'
            else:
                lines += '\n'
                bet_lines = []
                for item in config_list:
                    bet_lines.append('{indent}- {value}'.format(indent=''.rjust(level * indent, ' '),
                                                                value=cls.to_yaml(item, compact, indent, level + 1)))
                lines += '\n'.join(bet_lines)
        elif isinstance(config, basestring):
            # if it contains a \n then it's multiline
            lines = config.split('\n')
            if len(lines) == 1:
                lines = config
            else:
                lines = '|\n' + '\n'.join([line.rjust(level * indent, ' ') for line in lines])
        elif config is None or isinstance(config, NoneValue):
            lines = 'null'
        elif config is True:
            lines = 'true'
        elif config is False:
            lines = 'false'
        else:
            lines = str(config)
        return lines
718751
def dumb_property_dict(style):
    """"""
    return dict([(x.strip(), y.strip()) for x, y in [z.split(':', 1) for z in style.split(';') if ':' in z]]);
505979
def to_dict(self):
        
        if not isinstance(self.graph.loader, PartitioningLoader):
            return dict(msg="Config sharing disabled for non-partioned loader")

        if not hasattr(self.graph.loader, "secrets"):
            return dict(msg="Config sharing disabled if no secrets are labelled")

        def remove_nulls(dct):
            return {key: value for key, value in dct.items() if value is not None}

        return loads(
            dumps(self.graph.loader.config, skipkeys=True, default=lambda obj: None),
            object_hook=remove_nulls,
        )
144720
def zip_nested(arg0, *args, **kwargs):
  """"""
  # Python 2 do not support kwargs only arguments
  dict_only = kwargs.pop("dict_only", False)
  assert not kwargs

  # Could add support for more exotic data_struct, like OrderedDict
  if isinstance(arg0, dict):
    return {
        k: zip_nested(*a, dict_only=dict_only) for k, a in zip_dict(arg0, *args)
    }
  elif not dict_only:
    if isinstance(arg0, list):
      return [zip_nested(*a, dict_only=dict_only) for a in zip(arg0, *args)]
  # Singleton
  return (arg0,) + args
278169
def read_config(cls, configparser):
        """"""
        config = dict()
        config[cls._filename_re_key] = configparser.get(cls.__name__, cls._filename_re_key) \
            if configparser.has_option(cls.__name__, cls._filename_re_key) else None
        return config
602940
def from_dict(self, d: Dict[str, Any]) -> None:
        """"""
        for key, value in d.items():
            if key.isupper():
                self._setattr(key, value)

        logger.info("Config is loaded from dict: %r", d)
889803
def _parse_section_to_dict(cls, section_options, values_parser=None):
        
        value = {}
        values_parser = values_parser or (lambda val: val)
        for key, (_, val) in section_options.items():
            value[key] = values_parser(val)
        return value
512459
def tree_to_dict(cls, tree):
        
        specs = {}
        for k in tree.keys():
            spec_key = '.'.join(k)
            specs[spec_key] = {}
            for grp in tree[k].groups:
                kwargs = tree[k].groups[grp].kwargs
                if kwargs:
                    specs[spec_key][grp] = kwargs
        return specs
701617
def dict_conf(filename):
  

  f, ext = os.path.splitext(filename)
  ext = ext.lower()

  if ext == "conf" or ext == "ini":
    # python config via config parser

    config = ConfigParser()
    config.optionxform=str
    config.read(filename)
    rv = {}
    for section in config.sections():
      rv[section] = {}
      for key,value in config.items(section):
        rv[section][key] = value.strip('"').strip("'").decode("string_escape")
    return rv
  else:
    # other type of config, use munge
    if munge_config:
      src = munge_config.parse_url(filename)
      return src.cls().load(open(filename)).get("vodka")
    else:
      raise Exception("'%s' type of config encountered, install munge" % ext)
1299349
def _model_to_dict(model, ignore):
        
        return {attr: value for attr, value in model.__dict__.items()
                if not attr.startswith('_') and attr not in ignore}
75137
def _config_parse(self):
        """"""
        res = super(cfg.ConfigParser, self).parse(Backend._config_string_io)
        return res
1090506
def get_dataarg(args):
    
    for i, arg in enumerate(args):
        if is_nested_config_arg(arg):
            return i, arg
        elif is_std_config_arg(arg):
            return i, {"config": arg}
        elif isinstance(arg, (list, tuple)) and is_nested_config_arg(arg[0]):
            return i, arg[0]
    raise ValueError("Did not find configuration or data object in arguments: %s" % args)
1075016
def as_dict(self):
        """"""
        def conv(v):
            if isinstance(v, SerializableAttributesHolder):
                return v.as_dict()
            elif isinstance(v, list):
                return [conv(x) for x in v]
            elif isinstance(v, dict):
                return {x:conv(y) for (x,y) in v.items()}
            else:
                return v
        return {k.replace('_', '-'): conv(v) for (k, v) in self._attributes.items()}
328819
def get_config_dict(self):
        
        config_dict = {}
        for dotted_key, value in self.get_config_values().items():
            subkeys = dotted_key.split('.')
            d = config_dict
            for key in subkeys:
                d = d.setdefault(key, value if key == subkeys[-1] else {})
        return config_dict