예제 #1
0
def test_fill_defaults_simple_config(oh):
    @oh.register(with_defaults=True)
    def foo(required: int, optional: str = "default value"):
        return 42

    # test valid config
    filled = Config.from_str(
        """
        [a]
        @call = foo
        required = 1
        """
    )
    assert filled.a["required"] == 1
    assert filled.a["optional"] == "default value"

    # test invalid config
    filled = Config.from_str(
        """
        [a]
        @call = foo
        optional = "some value"
        """
    )
    with pytest.raises(RuntimeError):
        filled.a()
예제 #2
0
def test_save_as_dict():
    c = Config.from_str(TEST_CONFIG)
    d = Config(c.to_dict())
    assert c == d

    e = Config.from_str(TEST_CONFIG, interpolate=False)
    f = Config(e.to_dict())
    assert e == f
예제 #3
0
def test_save_as_json():
    c = Config.from_str(TEST_CONFIG)
    data = json.dumps(c)
    d = Config.from_json(data)
    assert d == c

    c = Config.from_str(TEST_CONFIG, interpolate=False)
    data = json.dumps(c)
    d = Config.from_json(data)
    assert d == c
예제 #4
0
def test_save_as_str():
    c = Config.from_str(TEST_CONFIG)
    d = Config.from_str(c.to_str())
    assert c == d

    e = Config.from_str(TEST_CONFIG, interpolate=False)
    f = Config.from_str(e.to_str(), interpolate=False)
    assert e == f

    h = Config.from_str(e.to_str())
    assert h == d
예제 #5
0
def test_save_as_pickle():
    c = Config.from_str(TEST_CONFIG)
    data = pickle.dumps(c)
    d = pickle.loads(data)
    assert isinstance(d, dict)
    assert not isinstance(d, Config)
    assert not isinstance(d, ConfigDict)
    assert not isinstance(d["a"], ConfigDict)
    assert d == c

    c = Config.from_str(TEST_CONFIG, interpolate=False)
    data = pickle.dumps(c)
    d = pickle.loads(data)
    assert isinstance(d, dict)
    assert not isinstance(d, Config)
    assert not isinstance(d, ConfigDict)
    assert d == c
예제 #6
0
def test_dict_access():
    c = Config.from_str("""
        [a]
        0 = -1
        x = 42
        [c.d]
        z = {"hello": "world"}
        """)
    assert c == {
        "a": {
            "0": -1,
            "x": 42
        },
        "c": {
            "d": {
                "z": {
                    "hello": "world"
                }
            }
        }
    }

    c["a"]["x"] = 43
    assert c["a"]["0"] == -1
    assert c["a"]["x"] == 43
    assert c["c"]["d"]["z"]["hello"] == "world"

    # test integer access
    assert c["a"][0] == -1
    c["a"][0] = 5
    assert c["a"][0] == 5

    with pytest.raises(ValueError):
        c["a"][-5] = 5

    with pytest.raises(TypeError):
        c["a"][5.0] = 5

    with pytest.raises(TypeError):
        c["a"][True] = 5

    with pytest.raises(TypeError):
        c["a"][None] = 5

    with pytest.raises(TypeError):
        c["a"][(1, 2)] = 5

    with pytest.raises(TypeError):
        c["a"][[1, 2]] = 5

    with pytest.raises(KeyError):
        c["a"]["b"]["c"]["d"]["e"] = 99
예제 #7
0
def test_no_interpolation():
    """Test that interpolation is correctly preserved."""
    c = Config.from_str(
        """
        [a]
        b = 1
        [c]
        d = "${a.b}"
        e = "hello${a.b}"
        f = ${a}
        """,
        interpolate=False
    )

    assert c["c"]["d"] == "${a.b}"
    assert c["c"]["e"] == "hello${a.b}"
    assert c["c"]["f"] == {"@ref": "a"}

    d = Config.from_str(c.to_str(), interpolate=True)
    assert d["c"]["d"] == "1"
    assert d["c"]["e"] == "hello1"
    assert d["c"]["f"] == {"b": 1}

    c = Config.from_str(
        """
        [a]
        b = 1
        [c.d]
        @ref = a
        """
    )
    assert c.flat["a.b"] == 1
    assert c.flat["c.d"] == {"@ref": "a"}

    d = Config.from_str(c.to_str(), interpolate=True)
    assert d.flat["a.b"] == 1
    assert d.flat["c.d"] == {"b": 1}
예제 #8
0
def test_dict_merging():
    c = Config({"a": {"b": 1, "c": 42}})
    c.update({"a": {"b": 123}})
    assert c == {"a": {"b": 123, "c": 42}}

    c = Config.from_str("""
        [a]
        x = 42
        [b.c]
        y = "asdf"
        """)
    c.update({"a": {"z": 1}}, merge_schema=True)
    c.update({"b": {"d": 2}}, merge_schema=True)
    assert c == {"a": {"x": 42, "z": 1}, "b": {"c": {"y": "asdf"}, "d": 2}}
예제 #9
0
def test_update():
    c = Config.from_str("""
        [a]
        x = 42
        [b.c]
        y = "asdf"
        """)

    with pytest.raises(ValidationError):
        c.update({"b": {"d": 2}})

    c.update({"b": {"d": 2}}, merge_schema=True)
    assert c == {"a": {"x": 42}, "b": {"c": {"y": "asdf"}, "d": 2}}

    c.update({"b": {"d": np.int64(64)}})
    assert c == {"a": {"x": 42}, "b": {"c": {"y": "asdf"}, "d": 64}}
    assert_valid_json(c)
예제 #10
0
def test_attribute_access():
    c = Config.from_str("""
        [a]
        x = 42
        [c.d]
        z = {"hello": "world"}
        """)
    assert c.a.x == 42
    assert c.c.d.z.hello == "world"

    c.a.x = 43
    assert c.a.x == 43

    with pytest.raises(ValidationError):
        c.a.y = 43

    with pytest.raises(AttributeError):
        c.a.b.c.d.e = 99
예제 #11
0
def test_load_merging():
    c = Config()
    c.load_str("""
        [a]
        b = 1
        [c]
        d = "foo"
        """)

    with pytest.raises(ValidationError):
        c.load_str("""
            [a]
            ab = "yeah"
            [aa]
            cd = "abba"
            """)

    assert c == {"a": {"b": 1}, "c": {"d": "foo"}}

    c.load_str(
        """
        [a]
        ab = "yeah"
        [aa]
        cd = "abba"
        """,
        merge_schema=True,
    )
    assert c == {
        "a": {
            "b": 1,
            "ab": "yeah"
        },
        "c": {
            "d": "foo"
        },
        "aa": {
            "cd": "abba"
        }
    }
예제 #12
0
def test_flat_access():
    c = Config.from_str("""
        [a]
        x = 42
        [b]
        y = "asdf"
        [c.d]
        z = {"hello": "world"}
        """)
    assert len(c.flat) == 3
    assert list(c.flat) == ["a.x", "b.y", "c.d.z.hello"]
    with pytest.raises(KeyError):
        c.flat["c.d.z.helloooo"]
    assert c.flat["c.d.z.hello"] == "world"

    with pytest.raises(TypeError):
        c.flat["x.y.z"] = 1

    with pytest.raises(TypeError):
        del c.flat["a.x"]
예제 #13
0
def test_illegal_types():
    with pytest.raises(TypeError):
        Config({"x": {None: 2}})

    with pytest.raises(TypeError):
        Config({"x": b"ugh"})

    with pytest.raises(TypeError):
        Config({"x": dt.datetime.utcnow()})

    with pytest.raises(TypeError):
        Config({"x": dt.timedelta(days=1)})

    with pytest.raises(TypeError):
        Config({"x": Decimal("3.3")})

    with pytest.raises(TypeError):
        Config({"x": complex(1, 2)})
예제 #14
0
def test_interpolation_lists():
    """Test that lists are preserved correctly"""
    c = Config.from_str(
        """
        [a]
        b = 1
        [c]
        d = ["hello ${a.b}", "world"]
        """,
        interpolate=False
    )
    assert c["c"]["d"] == ["hello ${a.b}", "world"]

    c = Config.from_str(
        """
        [a]
        b = 1
        [c]
        d = ["hello ${a.b}", "world"]
        """
    )
    assert c["c"]["d"] == ["hello 1", "world"]

    c = Config.from_str(
        """
        [a]
        b = 1
        [c]
        d = [${a.b}, "hello ${a.b}", "world"]
        """,
        interpolate=False
    )
    assert c["c"]["d"] == [{"@ref": "a.b"}, "hello ${a.b}", "world"]

    c = Config.from_str(
        """
        [a]
        b = 1
        [c]
        d = [${a.b}, "hello ${a.b}", "world"]
        """
    )
    assert c["c"]["d"] == [1, "hello 1", "world"]

    c = Config.from_str(
        """
        [a]
        b = 1
        [c]
        d = ["hello", ${a}]
        """
    )
    assert c["c"]["d"] == ["hello", {"b": 1}]

    with pytest.raises(ParseError):
        Config.from_str(
            """
            [a]
            b = 1
            [c]
            d = ["hello", "hello ${a}"]
            """
        )

    c = Config.from_str(
        """
        [a]
        b = 1
        [c]
        d = ["hello", {"x": ["hello ${a.b}"], "y": 2}]
        """
    )
    assert c["c"]["d"] == ["hello", {"x": ["hello 1"], "y": 2}]

    c = Config.from_str(
        """
        [a]
        b = 1
        [c]
        d = ["hello", {"x": [${a.b}], "y": 2}]
        """
    )
    assert c["c"]["d"] == ["hello", {"x": [1], "y": 2}]

    c = Config.from_str(
        """
        [a]
        b = 1
        c = "fof"
        [d]
        e = ${a}
        """
    )
    assert c.d.e == {"b": 1, "c": "fof"}
예제 #15
0
def test_2d_numpy_arrays(dtype):
    value = np.ones((5, 5), dtype=dtype)
    c = Config({"x": value})
    assert isinstance(c.x, type(value.tolist())) and c.x == value.tolist()
    assert_valid_json(c)
예제 #16
0
def test_numpy_scalars(dtype):
    value = np.ones(1, dtype=dtype)[0]
    c = Config({"x": value})
    assert isinstance(c.x, type(value.item())) and c.x == value.item()
    assert_valid_json(c)
예제 #17
0
def test_json_types(value):
    c = Config({"x": value})
    assert isinstance(c.x, type(value))
    assert c.x == value or (isinstance(c.x, float) and isnan(c.x)
                            and isinstance(value, float) and isnan(value))
    assert_valid_json(c)
예제 #18
0
def test_interpolation():
    with pytest.raises(ParseError):
        Config.from_str(
            """
            [a]
            foo = "hello"
            [b]
            bar = ${foo}
            """
        )

    c = Config.from_str(
        """
        [a]
        foo = "hello"
        [b]
        bar = ${a.foo}
        """
    )
    assert c["b"]["bar"] == "hello"

    c = Config.from_str(
        """
        [a]
        foo = "hello"
        [b]
        bar = "${a.foo}!"
        """
    )
    assert c["b"]["bar"] == "hello!"

    with pytest.raises(ParseError):
        Config.from_str(
            """
            [a]
            foo = "hello"
            [b]
            bar = ${a.foo}!
            """
        )

    with pytest.raises(ParseError):
        Config.from_str(
            """
            [a]
            foo = 15
            [b]
            bar = ${a.foo}!
            """
        )

    c = Config.from_str(
        """
        [a]
        foo = ["x", "y"]
        [b]
        bar = ${a.foo}
        """
    )
    assert c["b"]["bar"] == ["x", "y"]

    # Interpolation within the same section
    c = Config.from_str(
        """
        [a]
        foo = "x"
        bar = ${a.foo}
        baz = "${a.foo}y"
        """
    )
    assert c["a"]["bar"] == "x"
    assert c["a"]["baz"] == "xy"

    # multiple string interpolations
    c = Config.from_str(
        """
        [a]
        x = "x"
        y = 1
        z = 3.14159
        zz = "foo ${a.x} ${a.y} ${a.z}"
        """
    )
    assert c.a.zz == "foo x 1 3.14159"

    # test all types
    c = Config.from_str(
        """
        [a]
        int = 42
        float = 3.14159
        str = "foobar"
        bool = true
        null = null
        x = "${a.int} ${a.float} ${a.str} ${a.bool} ${a.null}"
        y = {"a": ${a.int}, "b": ${a.float}, "c": ${a.str}, "d": ${a.bool}, "e": ${a.null}}
        z = [${a.int}, ${a.float}, ${a.str}, ${a.bool}, ${a.null}]
        """
    )
    assert c.a.x == "42 3.14159 foobar True None"
    assert c.a.y == {"a": 42, "b": 3.14159, "c": "foobar", "d": True, "e": None}
    assert c.a.z == [42, 3.14159, "foobar", True, None]

    # leading and trailing text
    c = Config.from_str(
        """
        [a]
        b = "ergo"
        c = "cogito ${a.b} sum"
        """
    )
    assert c.a.c == "cogito ergo sum"

    # trailing spaces
    c = Config.from_str(
        """
        [a]
        b = "zip"
        c = ${a.b}   
        """
    )
    assert c.a.c == "zip"

    c = Config.from_str(
        """
        [a]
        b = "zip"
        c = "${a.b}${a.b}"
        """
    )
    assert c.a.c == "zipzip"

    with pytest.raises(ParseError):
        Config.from_str(
            """
            [a]
            b = "zip"
            c = ${a.b}${a.b}
            """
        )

    # nested data in string interpolation
    with pytest.raises(ParseError):
        Config.from_str(
            """
            [a]
            b = 1
            c = "fof"
            [d]
            e = "${a}"
            """
        )

    # wrong order
    with pytest.raises(ParseError):
        Config.from_str(
            """
            [a]
            b = ${d}
            [d]
            e = 1
            """
        )

    # cyclic references
    with pytest.raises(ParseError):
        Config.from_str(
            """
            [a]
            b = ${d.e}
            [d]
            e = ${a.b}
            """
        )

    # chained references
    c = Config.from_str(
        """
        [a]
        b = 1
        [c]
        d = ${a}
        [e]
        f = ${c.d.b}
        [g]
        h = ${e.f}
        """
    )
    assert c.flat["a.b"] == 1
    assert c.flat["c.d"] == {"b": 1}
    assert c.flat["e.f"] == 1
    assert c.flat["g.h"] == 1