def parse_to_dict(config): """Loads the ConfigParser object as a nested dictionary. Automatically converts strings representing ints and floats to their respective types, through the magic of ast.literal_eval. This functionality is extensible via the loads_methods list. Each loads (load string) method is tested in turn to see if it throws an exception. If all throw, we assume the value is meant to be string. Any values that you don't want to be converted should simply be surrounded with quote marks in the parset - then ast.literal_eval knows to load it as a string. Args: config: A ConfigParser object. Returns: Nested dict {sections -> keys -> values } representing parsed params. """ pars = adict() #'DEFAULT' section is not listed by ``sections()``, # but we sometimes (ab)use it. sections = config.sections() if len(config.items('DEFAULT')): sections.append('DEFAULT') for section_name in sections: if section_name not in pars: pars[section_name] = adict() for k, rawval in config.items(section_name): val = rawval for func in loads_methods: try: val = func(rawval) break # Drop out of loop if exception not thrown except (ValueError, SyntaxError): pass # Try the next method if val == rawval: logger.debug("Parsing section: [%s]\n" "Could not parse key-value pair:\n%s = %s\n" "-assuming string value", section_name, k, rawval) pars[section_name][k] = val return pars
def parse_to_dict(config): """Loads the ConfigParser object as a nested dictionary. Automatically converts strings representing ints and floats to their respective types, through the magic of ast.literal_eval. This functionality is extensible via the loads_methods list. Each loads (load string) method is tested in turn to see if it throws an exception. If all throw, we assume the value is meant to be string. Any values that you don't want to be converted should simply be surrounded with quote marks in the parset - then ast.literal_eval knows to load it as a string. Args: config: A ConfigParser object. Returns: Nested dict {sections -> keys -> values } representing parsed params. """ pars = adict() #'DEFAULT' section is not listed by ``sections()``, # but we sometimes (ab)use it. sections = config.sections() if len(config.items('DEFAULT')): sections.append('DEFAULT') for section_name in sections: if section_name not in pars: pars[section_name] = adict() for k, rawval in config.items(section_name): val = rawval for func in loads_methods: try: val = func(rawval) break # Drop out of loop if exception not thrown except (ValueError, SyntaxError): pass # Try the next method if val == rawval: logger.debug( "Parsing section: [%s]\n" "Could not parse key-value pair:\n%s = %s\n" "-assuming string value", section_name, k, rawval) pars[section_name][k] = val return pars
def test_pickle(self): """ check if we can pickle and unpickle the adict """ cucumis_sativus = adict(data) pickled = pickle.dumps(cucumis_sativus) unpickled = pickle.loads(pickled) self.assertEqual(cucumis_sativus, unpickled)
def fetch_config(dataset_id): """ Retrieve the stored config for given dataset id Returns: nested dict [section][key] -> [value] """ logger.info("fetching config from database for dataset %s" % dataset_id) error = "type in database is %s but we only support %s" result = execute(fetch_query, {'dataset': dataset_id}).fetchall() config = adict() for section, key, value, type_ in result: if type_ not in (t.__name__ for t in types): msg = error % (type_, ", ".join(t.__name__ for t in types)) logger.error(msg) raise TypeError(msg) converted = eval(type_)(value) if not section in config: config[section] = adict() config[section][key] = converted return config