def test_config_to_str_simple_promises(): """Test that references to function registries without arguments are serialized inline as dict.""" config_str = """[section]\nsubsection = {"@registry":"value"}""" config = Config().from_str(config_str) assert config["section"]["subsection"]["@registry"] == "value" assert config.to_str() == config_str
def test_config_no_interpolation(d): """Test that interpolation is correctly preserved. The parametrized value is the final divider (${a.b} vs. ${a:b}). Both should now work and be valid. The double {{ }} in the config strings are required to prevent the references from being interpreted as an actual f-string variable. """ c_str = f"""[a]\nb = 1\n\n[c]\nd = ${{a{d}b}}\ne = \"hello${{a{d}b}}"\nf = ${{a}}""" config = Config().from_str(c_str, interpolate=False) assert not config.is_interpolated assert config["c"]["d"] == f"${{a{d}b}}" assert config["c"]["e"] == f'"hello${{a{d}b}}"' assert config["c"]["f"] == "${a}" config2 = Config().from_str(config.to_str(), interpolate=True) assert config2.is_interpolated assert config2["c"]["d"] == 1 assert config2["c"]["e"] == "hello1" assert config2["c"]["f"] == {"b": 1} config3 = config.interpolate() assert config3.is_interpolated assert config3["c"]["d"] == 1 assert config3["c"]["e"] == "hello1" assert config3["c"]["f"] == {"b": 1} # Bad non-serializable value cfg = {"x": {"y": numpy.asarray([[1, 2], [4, 5]], dtype="f"), "z": f"${{x{d}y}}"}} with pytest.raises(ConfigValidationError): Config(cfg).interpolate()
def test_config_to_str_order(): """Test that Config.to_str orders the sections.""" config = {"a": {"b": {"c": 1, "d": 2}, "e": 3}, "f": {"g": {"h": {"i": 4, "j": 5}}}} expected = ( "[a]\ne = 3\n\n[a.b]\nc = 1\nd = 2\n\n[f]\n\n[f.g]\n\n[f.g.h]\ni = 4\nj = 5" ) config = Config(config) assert config.to_str() == expected
def test_config_to_str_roundtrip(): cfg = {"cfg": {"foo": False}} config_str = Config(cfg).to_str() assert config_str == "[cfg]\nfoo = false" config = Config().from_str(config_str) assert dict(config) == cfg cfg = {"cfg": {"foo": "false"}} config_str = Config(cfg).to_str() assert config_str == '[cfg]\nfoo = "false"' config = Config().from_str(config_str) assert dict(config) == cfg # Bad non-serializable value cfg = {"cfg": {"x": numpy.asarray([[1, 2, 3, 4], [4, 5, 3, 4]], dtype="f")}} config = Config(cfg) with pytest.raises(ConfigValidationError): config.to_str() # Roundtrip with variables: preserve variables correctly (quoted/unquoted) config_str = """[a]\nb = 1\n\n[c]\nd = ${a:b}\ne = \"hello${a:b}"\nf = "${a:b}\"""" config = Config().from_str(config_str, interpolate=False) assert config.to_str() == config_str
def test_config_custom_sort_preserve(): """Test that sort order is preserved when merging and copying configs, or when configs are filled and resolved.""" cfg = {"x": {}, "y": {}, "z": {}} section_order = ["y", "z", "x"] expected = "[y]\n\n[z]\n\n[x]" config = Config(cfg, section_order=section_order) assert config.to_str() == expected config2 = config.copy() assert config2.to_str() == expected config3 = config.merge({"a": {}}) assert config3.to_str() == f"{expected}\n\n[a]" config4 = Config(config) assert config4.to_str() == expected config_str = """[a]\nb = 1\n[c]\n@cats = "catsie.v1"\nevil = true\n\n[t]\n x = 2""" section_order = ["c", "a", "t"] config5 = Config(section_order=section_order).from_str(config_str) assert list(config5.keys()) == section_order filled = my_registry.fill_config(config5) assert filled.section_order == section_order