def test_reload(): # type: ignore os.environ.update((PREFIX + "__" + k.replace(".", "__").upper(), str(v)) for k, v in DICT.items()) cfg = config_from_env(PREFIX, lowercase_keys=True) assert cfg == config_from_dict(dict((k, str(v)) for k, v in DICT.items())) os.environ[PREFIX + "__" + "A2__B2__C3"] = "updated" assert cfg == config_from_dict(dict((k, str(v)) for k, v in DICT.items())) cfg.reload() d = DICT.copy() d["a2.b2.c3"] = "updated" assert cfg == config_from_dict(dict((k, str(v)) for k, v in d.items()))
def test_reload_toml(): # type: ignore with tempfile.NamedTemporaryFile() as f: f.file.write(TOML.encode()) f.file.flush() cfg = config_from_toml(f.name, read_from_file=True) assert cfg == config_from_dict(DICT) f.file.seek(0) f.file.truncate(0) f.file.write(b'[owner]\nname = "ABC"\n') f.file.flush() cfg.reload() assert cfg == config_from_dict({"owner.name": "ABC"})
def test_configset_delitem(): # type: ignore cfg = ConfigurationSet( config_from_dict(DICT, lowercase_keys=True), config_from_dict(PROTECTED, lowercase_keys=True), ) assert len(cfg) == 17 del cfg["a1.b1"] assert len(cfg) == 14 with raises(KeyError): del cfg["z"]
def test_reload_json(): # type: ignore with tempfile.NamedTemporaryFile() as f: f.file.write(JSON.encode()) f.file.flush() cfg = config_from_json(f.name, read_from_file=True) assert cfg == config_from_dict(DICT) f.file.seek(0) f.file.truncate(0) f.file.write(b'{"test": 1}') f.file.flush() cfg.reload() assert cfg == config_from_dict({"test": 1})
def test_get(): # type: ignore cfg = ConfigurationSet( config_from_dict(DICT2_1, lowercase_keys=True), config_from_dict(DICT2_2, lowercase_keys=True), config_from_env(prefix=PREFIX, lowercase_keys=True), ) assert cfg.get("a2.b2") == config_from_dict({ "c1": 10, "c2": "YWJjZGVmZ2g=", "c3": "abcdefgh" }) assert cfg.get("a2.b5", "1") == "1"
def test_same_as_configuration(): # type: ignore cfg = config_from_dict(DICT2_1, lowercase_keys=True) cfgset = ConfigurationSet(config_from_dict(DICT2_1, lowercase_keys=True)) assert cfg.get_dict("a2") == cfgset.get_dict("a2") assert cfg.a2.as_dict() == cfgset.a2.as_dict() assert dict(cfg.a2) == dict(cfgset.a2) assert dict(cfg.a2) == dict(cfg.a2.items()) assert dict(cfgset.a2) == dict(cfgset.a2.items()) assert cfg.as_dict() == cfgset.as_dict() assert dict(cfg) == dict(cfgset)
def test_repr(): # type: ignore import sys path = os.path.join(os.path.dirname(__file__), 'python_config.py') cfg = ConfigurationSet(config_from_dict(DICT2_1), config_from_dict(DICT2_2), config_from_env(prefix=PREFIX), config_from_python(path, prefix='CONFIG')) joined_dicts = dict((k, str(v)) for k, v in DICT1.items()) joined_dicts.update(DICT2_1) joined_dicts.update(DICT2_2) joined_dicts['sys.version'] = sys.hexversion assert str(dict( (k.lower(), v) for k, v in joined_dicts.items())) in repr(cfg)
def test_fails(): # type: ignore cfg = ConfigurationSet(config_from_dict(DICT2_1), config_from_dict(DICT2_2), config_from_env(prefix=PREFIX)) with raises(KeyError, message="a1.b2.c3.d4"): assert cfg["a1.b2.c3.d4"] is Exception with raises(KeyError, message="'c4'"): assert cfg.a1.b2.c4 is Exception with raises(ValueError, message="Expected a valid True or False expression."): assert cfg["a1.b2"].get_bool("c3") is Exception
def test_load_env(): # type: ignore cfg = ConfigurationSet( config_from_dict(DICT2_1, lowercase_keys=True), config_from_dict(DICT2_2, lowercase_keys=True), config_from_env(prefix=PREFIX, lowercase_keys=True), ) # from env assert cfg["a1.b1.c1"] == "1" assert cfg["a1.b1"].get_int("c1") == 1 assert cfg["a1.b1"].as_dict() == {"c1": "1", "c2": "2", "c3": "3"} assert cfg["a1.b2"].as_dict() == {"c1": "a", "c2": "True", "c3": "1.1"} # from dict assert cfg["a2.b1.c1"] == "f" assert cfg["a2.b2"].as_dict() == {"c1": 10, "c2": "YWJjZGVmZ2g=", "c3": "abcdefgh"}
def test_configset_update(): # type: ignore cfg = ConfigurationSet( config_from_dict(DICT, lowercase_keys=True), config_from_dict(PROTECTED, lowercase_keys=True), ) assert len(cfg) == 17 assert cfg["a1.b2.c1"] == "a" cfg.update(NESTED) assert len(cfg) == 17 assert cfg["a1.b2.c1"] == "a0" cfg.update({"important_password_2": "abc"}) assert len(cfg) == 18
def test_reload(): # type: ignore with tempfile.NamedTemporaryFile() as f: f.file.write(INI.encode()) f.file.flush() cfg = config_from_ini(open(f.name, "rt"), read_from_file=True) assert cfg == config_from_dict( dict((k, str(v)) for k, v in DICT.items())) f.file.write(b"\n[section4]\nkey10 = 1\n") f.file.flush() cfg = config_from_ini(open(f.name, "rt"), read_from_file=True) cfg2 = config_from_dict(dict((k, str(v)) for k, v in DICT.items())) cfg2["section4.key10"] = "1" assert cfg == cfg2
def test_fails(): # type: ignore cfg = ConfigurationSet( config_from_dict(DICT2_1, lowercase_keys=True), config_from_dict(DICT2_2, lowercase_keys=True), config_from_env(prefix=PREFIX, lowercase_keys=True), ) with pytest.raises(KeyError, match="a1.b2.c3.d4"): assert cfg["a1.b2.c3.d4"] is Exception with pytest.raises(KeyError, match="c4"): assert cfg.a1.b2.c4 is Exception with pytest.raises(ValueError, match="Expected a valid True or False expression."): assert cfg["a1.b2"].get_bool("c3") is Exception
def test_dict_methods_keys_values(): # type: ignore cfg = ConfigurationSet( config_from_dict(DICT2_1, lowercase_keys=True), config_from_dict(DICT2_2, lowercase_keys=True), config_from_env(prefix=PREFIX, lowercase_keys=True), ) assert sorted(cfg.keys()) == [ "a1", "a2", ] assert dict(zip(cfg.keys(), cfg.values())) == { "a1": { "b1.c1": "1", "b1.c2": "2", "b1.c3": "3", "b2.c1": "a", "b2.c2": "True", "b2.c3": "1.1", }, "a2": { "b1.c1": "f", "b1.c2": False, "b1.c3": None, "b2.c1": 10, "b2.c2": "YWJjZGVmZ2g=", "b2.c3": "abcdefgh", }, } with cfg.dotted_iter(): assert sorted(cfg.keys()) == [ "a1.b1.c1", "a1.b1.c2", "a1.b1.c3", "a1.b2.c1", "a1.b2.c2", "a1.b2.c3", "a2.b1.c1", "a2.b1.c2", "a2.b1.c3", "a2.b2.c1", "a2.b2.c2", "a2.b2.c3", ] assert dict(zip(cfg.keys(), cfg.values())) == cfg.as_dict()
def test_configset_pop(): # type: ignore cfg = ConfigurationSet( config_from_dict(DICT, lowercase_keys=True), config_from_dict(PROTECTED, lowercase_keys=True), ) with cfg.dotted_iter(): assert len(cfg) == 17 assert cfg.pop("a2.b1.c1") == "f" assert cfg.pop("a2.b1.c1", "something") == "something" with raises(KeyError): cfg.pop("a2.b1.c1") with cfg.dotted_iter(): assert len(cfg) == 16
def test_in(): # type: ignore cfg = config_from_dict(DICT, lowercase_keys=True) assert "x" not in cfg assert "a1" in cfg assert "a1.b2" in cfg assert "a1.b2.c3" in cfg
def test_load_env(): # type: ignore cfg = ConfigurationSet(config_from_dict(DICT2_1), config_from_dict(DICT2_2), config_from_env(prefix=PREFIX)) # from env assert cfg["a1.b1.c1"] == '1' assert cfg["a1.b1"].get_int('c1') == 1 assert cfg["a1.b1"].as_dict() == {"c1": '1', "c2": '2', "c3": '3'} assert cfg["a1.b2"].as_dict() == {"c1": "a", "c2": 'True', "c3": '1.1'} # from dict assert cfg["a2.b1.c1"] == 'f' assert cfg["a2.b2"].as_dict() == { 'c1': 10, 'c2': 'YWJjZGVmZ2g=', 'c3': 'abcdefgh' }
def test_copy(): # type: ignore cfg = config_from_dict(DICT, lowercase_keys=True) assert len(cfg) == 12 cfg2 = cfg.copy() assert cfg == cfg2
def test_load_ini_filename(): # type: ignore with tempfile.NamedTemporaryFile() as f: f.file.write(INI.encode()) f.file.flush() cfg = config_from_ini(f.name, read_from_file=True) assert cfg == config_from_dict(dict((k, str(v)) for k, v in DICT.items()))
def test_dict_methods_dict(): # type: ignore cfg = config_from_dict(DICT, lowercase_keys=True) a1 = { "b1.c1": 1, "b1.c2": 2, "b1.c3": 3, "b2.c1": "a", "b2.c2": True, "b2.c3": 1.1, } a2 = { "b1.c1": "f", "b1.c2": False, "b1.c3": None, "b2.c1": 10, "b2.c2": "YWJjZGVmZ2g=", "b2.c3": "abcdefgh", } # as_dict and get_dict always returns dotted keys assert cfg.as_dict() == {k.lower(): v for k, v in DICT.items()} assert cfg.get_dict("a1") == a1 assert cfg.get_dict("a1.b2") == {"c1": "a", "c2": True, "c3": 1.1} # dict() uses the iterator methods and will return a nested dict by default assert dict(cfg) == {"a1": a1, "a2": a2} with cfg.dotted_iter(): # as_dict and get_dict always returns dotted keys assert cfg.as_dict() == {k.lower(): v for k, v in DICT.items()} assert cfg.get_dict("a1") == a1 assert cfg.get_dict("a1.b2") == {"c1": "a", "c2": True, "c3": 1.1} # in this case the iterators will return all the (dotted) keys, so dict() is the same as .as_dict() assert dict(cfg) == {k.lower(): v for k, v in DICT.items()}
def test_attribute_dict_1(): # type: ignore definitions = { "my.var": ["hello"], "var": ["1", "2"], "var2": { "a": { "c": 1, "d": 10 }, "b": 2 }, } cfg = config_from_dict(definitions, interpolate=True) d = cfg.as_attrdict() assert isinstance(d, dict) assert isinstance(d, AttributeDict) assert d.var == ["1", "2"] assert d.my.var == ["hello"] assert d.var2.a == {"c": 1, "d": 10} with raises(AttributeError): assert d.var3 d.var3 = "abc" assert d.var3 == "abc"
def load_complete_cfg(self): """Loads the complete configuration""" if os.path.isfile(self._filename): path, filename = os.path.split(self._filename) if self.num_parent_directories == 0: self._complete_cfg = config.ConfigurationSet( config.config_from_toml(self._filename, read_from_file=True), ) elif self.num_parent_directories == 1: self._complete_cfg = config.ConfigurationSet( config.config_from_toml(self._filename, read_from_file=True), config.config_from_toml(os.path.join(path, '..', filename), read_from_file=True), ) elif self.num_parent_directories == 2: self._complete_cfg = config.ConfigurationSet( config.config_from_toml(self._filename, read_from_file=True), config.config_from_toml(os.path.join(path, '..', filename), read_from_file=True), config.config_from_toml(os.path.join( path, '..', '..', filename), read_from_file=True)) else: raise ValueError( 'Unsupported value for "num_parent_directories"') else: self._complete_cfg = config.ConfigurationSet( config.config_from_dict(dict())) self.add_ephemeral_attributes()
def test_interpolation(): # type: ignore cfg = config_from_dict(VALUES, lowercase_keys=True, interpolate=True) assert cfg["var3"] == "test" assert cfg["var2"] == "is a test" assert cfg["var1"] == "This is a test" assert cfg.var1 == "This is a test"
def test_equality(): # type: ignore import python_config cfg = config_from_python(python_config, prefix="CONFIG", lowercase_keys=True) assert cfg == config_from_dict(DICT, lowercase_keys=True)
def test_multiple_interpolation(): # type: ignore cfg = config_from_dict(MULTI, lowercase_keys=True, interpolate=True) assert cfg["var3"] == "test" assert cfg["var2"] == "repeat test" assert cfg["var1"] == "This is a repeat test test" assert cfg.var1 == "This is a repeat test test"
def test_interpolation_with_formatting(): # type: ignore cfg = config_from_dict(VALUES_FMT, lowercase_keys=True, interpolate=True) assert cfg["val"] == 1.23456 assert cfg["with_sign"] == "+1.234560" assert cfg["percentage"] == "123.456%" assert cfg.percentage == "123.456%"
def test_separator(): # type: ignore from . import python_config_2 cfg = config_from_python( python_config_2, prefix="CONFIG", separator="__", lowercase_keys=True ) assert cfg == config_from_dict(DICT, lowercase_keys=True)
def test_list_3(): # type: ignore definitions = {"my.var": ["hello"], "var": ["1", "2"]} cfg = config_from_dict(definitions, interpolate=True) assert cfg.my.as_dict() == {"var": ["hello"]} cfg.my.as_dict()["var"].insert(0, "hello again") assert cfg.my.as_dict() == {"var": ["hello"]}
def test_list(): # type: ignore cfg = config_from_dict(DICT, lowercase_keys=False) assert sorted(cfg) == ["A1", "a1", "a2"] assert list(cfg) == list(reversed(cfg))[::-1] with cfg.dotted_iter(): assert sorted(cfg) == sorted(DICT.keys()) assert list(cfg) == list(reversed(cfg))[::-1]
def test_load_dotenv_filename(): # type: ignore with tempfile.NamedTemporaryFile() as f: f.file.write(DOTENV.encode()) f.file.flush() cfg = config_from_dotenv(f.name, read_from_file=True, lowercase_keys=True) assert cfg == config_from_dict(dict((k, str(v)) for k, v in DICT.items()))
def test_get_dict(): # type: ignore cfg = ConfigurationSet( config_from_dict(DICT2_1, lowercase_keys=True), config_from_dict(DICT2_2, lowercase_keys=True), config_from_env(prefix=PREFIX, lowercase_keys=True), ) a2 = { "b2.c1": 10, "b1.c1": "f", "b1.c2": False, "b1.c3": None, "b2.c1": 10, "b2.c2": "YWJjZGVmZ2g=", "b2.c3": "abcdefgh", } a2nested = { "b1": { "c1": "f", "c2": False, "c3": None }, "b2": { "c1": 10, "c2": "YWJjZGVmZ2g=", "c3": "abcdefgh" }, } assert cfg.get_dict("a2") == a2 assert cfg.a2.as_dict() == a2 assert dict(cfg.a2) == a2nested with cfg.dotted_iter(): assert cfg.get_dict("a2") == a2 assert cfg.a2.as_dict() == a2 # note that this still returns he nested dict since the dotted iteration # impacts only the parent cfg, not cfg.a assert dict(cfg.a2) == a2nested # to use dotted iteration for children, we need to explicitly set it with cfg.a2.dotted_iter() as cfg_a2: assert dict(cfg_a2) == a2 with pytest.raises(KeyError): assert cfg.get_dict("a3") is Exception assert dict(cfg.a2) == dict(cfg.a2.items())