def add_config(self, cfg=None, **kw_conf): """ Add a configuration entry to this ingredient/experiment. Can be called either with a dictionary or with keyword arguments. The dictionary or the keyword arguments will be converted into a :class:`~sacred.config_scope.ConfigDict`. :param cfg: Configuration dictionary to add to this ingredient/experiment. :type cfg: dict :param kw_conf: Configuration entries to be added to this ingredient/experiment. """ if cfg is not None and kw_conf: raise ValueError("cannot combine keyword config with " "positional argument") if cfg is None: if not kw_conf: raise ValueError("attempted to add empty config") self.configurations.append(ConfigDict(kw_conf)) elif isinstance(cfg, dict): self.configurations.append(ConfigDict(cfg)) else: raise TypeError("Invalid argument type {}".format(type(cfg)))
def test_add_config_dict_sequential(): # https://github.com/IDSIA/sacred/issues/409 @ConfigScope def cfg1(): dictnest2 = { 'key_1': 'value_1', 'key_2': 'value_2' } cfg1dict = ConfigDict(cfg1()) @ConfigScope def cfg2(): dictnest2 = { 'key_2': 'update_value_2', 'key_3': 'value3', 'key_4': 'value4' } cfg2dict = ConfigDict(cfg2()) final_config_scope, _ = chain_evaluate_config_scopes([cfg1, cfg2]) assert final_config_scope == { 'dictnest2': { 'key_1': 'value_1', 'key_2': 'update_value_2', 'key_3': 'value3', 'key_4': 'value4' } } final_config_dict, _ = chain_evaluate_config_scopes([cfg1dict, cfg2dict]) assert final_config_dict == final_config_scope
def test_add_config_dict_sequential(): # https://github.com/IDSIA/sacred/issues/409 @ConfigScope def cfg1(): dictnest2 = {"key_1": "value_1", "key_2": "value_2"} cfg1dict = ConfigDict(cfg1()) @ConfigScope def cfg2(): dictnest2 = { "key_2": "update_value_2", "key_3": "value3", "key_4": "value4" } cfg2dict = ConfigDict(cfg2()) final_config_scope, _ = chain_evaluate_config_scopes([cfg1, cfg2]) assert final_config_scope == { "dictnest2": { "key_1": "value_1", "key_2": "update_value_2", "key_3": "value3", "key_4": "value4", } } final_config_dict, _ = chain_evaluate_config_scopes([cfg1dict, cfg2dict]) assert final_config_dict == final_config_scope
def test_conf_scope_contains_presets(): conf_dict = ConfigDict({"answer": 42}) cfg = conf_dict(preset={"a": 21, "unrelated": True}) assert set(cfg.keys()) == {"a", "answer", "unrelated"} assert cfg["a"] == 21 assert cfg["answer"] == 42 assert cfg["unrelated"] is True
def test_conf_scope_contains_presets(): conf_dict = ConfigDict({"answer": 42}) cfg = conf_dict(preset={'a': 21, 'unrelated': True}) assert set(cfg.keys()) == {'a', 'answer', 'unrelated'} assert cfg['a'] == 21 assert cfg['answer'] == 42 assert cfg['unrelated'] is True
def test_fixed_subentry_of_preset(): config_dict = ConfigDict({}) cfg = config_dict(preset={'d': {'a': 1, 'b': 2}}, fixed={'d': {'a': 10}}) assert set(cfg.keys()) == {'d'} assert set(cfg['d'].keys()) == {'a', 'b'} assert cfg['d']['a'] == 10 assert cfg['d']['b'] == 2
def _create_config_dict(cfg_or_file, kw_conf): if cfg_or_file is not None and kw_conf: raise ValueError("cannot combine keyword config with " "positional argument") if cfg_or_file is None: if not kw_conf: raise ValueError("attempted to add empty config") return ConfigDict(kw_conf) elif isinstance(cfg_or_file, dict): return ConfigDict(cfg_or_file) elif isinstance(cfg_or_file, basestring): if not os.path.exists(cfg_or_file): raise IOError('File not found {}'.format(cfg_or_file)) abspath = os.path.abspath(cfg_or_file) return ConfigDict(load_config_file(abspath)) else: raise TypeError("Invalid argument type {}".format( type(cfg_or_file)))
def test_fixed_subentry_of_preset(): config_dict = ConfigDict({}) cfg = config_dict(preset={"d": {"a": 1, "b": 2}}, fixed={"d": {"a": 10}}) assert set(cfg.keys()) == {"d"} assert set(cfg["d"].keys()) == {"a", "b"} assert cfg["d"]["a"] == 10 assert cfg["d"]["b"] == 2
def run_named_config(self, config_name): if os.path.exists(config_name): nc = ConfigDict(load_config_file(config_name)) else: nc = self.named_configs[config_name] cfg = nc(fixed=self.get_config_updates_recursive(), preset=self.presets, fallback=self.fallback) return undogmatize(cfg)
def test_add_config_dict_sequential(): # https://github.com/IDSIA/sacred/issues/409 adict = ConfigDict(dict(dictnest2={"key_1": "value_1", "key_2": "value_2"})) bdict = ConfigDict( dict( dictnest2={"key_2": "update_value_2", "key_3": "value3", "key_4": "value4"} ) ) final_config = bdict(preset=adict()) assert final_config == { "dictnest2": { "key_1": "value_1", "key_2": "update_value_2", "key_3": "value3", "key_4": "value4", } }
def conf_dict(): cfg = ConfigDict( { "a": 1, "b": 2.0, "c": True, "d": "string", "e": [1, 2, 3], "f": {"a": "b", "c": "d"}, } ) return cfg
def conf_dict(): cfg = ConfigDict({ "a": 1, "b": 2.0, "c": True, "d": 'string', "e": [1, 2, 3], "f": { 'a': 'b', 'c': 'd' }, }) return cfg
def run_named_config(self, config_name): if os.path.isfile(config_name): nc = ConfigDict(load_config_file(config_name)) else: if config_name not in self.named_configs: raise NamedConfigNotFoundError(named_config=config_name, available_named_configs=tuple( self.named_configs.keys())) nc = self.named_configs[config_name] cfg = nc(fixed=self.get_config_updates_recursive(), preset=self.presets, fallback=self.fallback) return undogmatize(cfg)
def set_up_config(self): if self.config is not None: return self.config # gather presets fallback = {} for sr_path, subrunner in self.subrunners.items(): if self.path and is_prefix(self.path, sr_path): path = sr_path[len(self.path):].strip('.') set_by_dotted_path(fallback, path, subrunner.config) else: set_by_dotted_path(fallback, sr_path, subrunner.config) # dogmatize to make the subrunner configurations read-only const_fallback = dogmatize(fallback) const_fallback.revelation() self.config = {} # named configs first cfg_list = [] for ncfg in self.named_configs_to_use: if os.path.exists(ncfg): cfg_list.append(ConfigDict(load_config_file(ncfg))) else: cfg_list.append(self.named_configs[ncfg]) self.config_updates, _ = chain_evaluate_config_scopes( cfg_list, fixed=self.config_updates, preset=self.config, fallback=const_fallback) # unnamed (default) configs second self.config, self.summaries = chain_evaluate_config_scopes( self.config_scopes, fixed=self.config_updates, preset=self.config, fallback=const_fallback) self.get_config_modifications()
def use_named_config(self, config_name): if os.path.exists(config_name): self.named_configs_to_use.append( ConfigDict(load_config_file(config_name))) else: self.named_configs_to_use.append(self.named_configs[config_name])
def test_conf_scope_handles_numpy_bools(): cfg = ConfigDict({"a": opt.np.bool_(1)}) assert 'a' in cfg() assert cfg()['a']
def test_config_dict_accepts_special_types(value): assert ConfigDict({"special": value})()['special'] == value
def test_config_dict_raises_on_invalid_keys(key): with pytest.raises(KeyError): ConfigDict({key: True})
def test_conf_scope_does_not_contain_fallback(): config_dict = ConfigDict({"answer": 42}) cfg = config_dict(fallback={'a': 21, 'b': 10}) assert set(cfg.keys()) == {'answer'}
def test_config_dict_raises_on_invalid_values(value): with pytest.raises(ValueError): ConfigDict({"invalid": value})