Пример #1
0
def test_prefix_standard():
    Schalter.clear()

    @Schalter.prefix("test")
    @Schalter.configure("a")
    def foo(*, a, b=3):
        return a

    Schalter["test/a"] = 3
    foo()

    @Schalter.prefix("b")
    @Schalter.configure
    def bar(*, b: int, c: str):
        return b, c

    Schalter["b/b"] = 2
    Schalter["b/c"] = "baz"
    assert bar() == (2, "baz")

    @Schalter.configure("non_prefixed")
    @Schalter.prefix("some_prefix")
    @Schalter.configure("prefixed")
    def baz(*, prefixed, non_prefixed):
        return prefixed, non_prefixed

    Schalter["some_prefix/prefixed"] = 123
    Schalter["non_prefixed"] = 456
    assert baz() == (123, 456)

    with pytest.raises(KeyError):
        _ = Schalter["prefixed"]
    with pytest.raises(KeyError):
        _ = Schalter["some_prefix/non_prefixed"]
Пример #2
0
def test_misc():
    Schalter.clear()

    # make sure that this does not configure the function arg 'a'
    # and does not contain a config value 'b'
    @Schalter.configure(b="a")
    def foo(*, a: int = 4, b: int):
        return a * b

    assert foo(b=5) == 20
    assert Schalter["a"] == 5
    assert not bool("b" in Schalter.get_config())
    assert "b" not in Schalter.get_config()
    assert not bool("b" in Schalter)
    with pytest.raises(KeyError):
        _ = Schalter["b"]

    Schalter["c"] = 0
    Schalter["d"] = 1

    @Schalter.configure(c="d", d="c")
    def bar(*, c: int = 4, d: int = 5):
        return c, d

    assert Schalter["c"] == 0
    assert Schalter["d"] == 1
    assert (1, 0) == bar()
Пример #3
0
def test_functions_callable():
    Schalter.clear()

    @Schalter.configure("x")
    def foo(*, x):
        _ = x

    # This raises a key error, because there is no value for x
    # instead of a TypeError for a missing argument
    with pytest.raises(KeyError):
        foo()

    @Schalter.configure("a")
    def not_callable(*, c, a):
        _ = c, a

    # c is a kwonly arg that is not configured. May not be marked as default available.
    with pytest.raises(TypeError):
        not_callable()

    @Schalter.configure("a")
    @Schalter.configure("c")
    def is_callable(*, c, a):
        _ = c, a

    Schalter["a"] = 0
    Schalter["c"] = 0
    is_callable()
Пример #4
0
def test_subset_configures_and_overrides():
    Schalter.clear()

    @Schalter.configure("a")
    def foo(*, a: int = 1, b: int = 2):
        return a * b

    assert Schalter["a"] == 1
    with pytest.raises(KeyError):
        _ = Schalter["b"]

    @Schalter.configure("b")
    def bar(*, a: int = 2, b: int = 3):
        return a * b

    assert Schalter["b"] == 3
    assert bar() == 6

    @Schalter.configure
    def baz(*, a, b):
        return a * b

    # Schalter decorator marks the kwonly args as 'with default'
    # to make this call possible
    assert baz() == 3
    assert foo(b=3) == 3
    # default is overridden
    assert baz(a=7) == 21
    assert baz(b=4) == 28
    assert foo(b=3) == 21
    assert bar() == 8
Пример #5
0
def test_do_not_override_with_default_values():
    Schalter.clear()
    # A (later defined) default value does not override a manually supplied parameter.

    Schalter["constant"] = 4

    @Schalter.configure("constant")
    def foo(*, constant=-1):
        return constant

    assert foo() == 4
Пример #6
0
def test_default_config():
    Schalter.clear()
    d = Schalter.get_config()
    assert type(d) == Schalter
    assert len(d.config) == 0

    @Schalter.configure()
    def foo(*, a):
        pass

    foo(a=3)
    assert Schalter["a"] == 3
Пример #7
0
def test_prevent_prefix_with_default_values():
    Schalter.clear()

    def wrapper():
        @Schalter.prefix("p")
        @Schalter.configure
        def foo(*, some_arg=1):
            pass

        assert Schalter['p/some_arg'] == 1

    with pytest.raises(NotImplementedError):
        wrapper()
Пример #8
0
def test_scoped_function():
    Schalter.clear()

    @Schalter.scoped_configure
    def foo(*, a):
        return a

    @Schalter.Scope("A")
    def do_stuff_a():
        foo(a=3)

    @Schalter.Scope("B")
    def do_stuff_b():
        foo(a=3)
Пример #9
0
def test_multiple_prefixed_configures():
    Schalter.clear()

    Schalter["p/leaf_a"] = 8
    Schalter["p/leaf_b"] = "foo"

    @Schalter.prefix("p")
    @Schalter.configure("leaf_a")
    @Schalter.configure("leaf_b")
    def foo(_unused, *, leaf_a, leaf_b):
        return _unused, leaf_a, leaf_b

    with pytest.raises(TypeError):
        _ = foo()

    assert foo(None) == (None, 8, "foo")
Пример #10
0
def test_multiple_configures():
    Schalter.clear()

    @Schalter.configure("a")
    @Schalter.configure("b")
    def foo(*, a, b, c, d):
        return a, b, c, d

    with pytest.raises(KeyError):
        _aa, _bb, _cc, _dd = foo(c=3, d=4)

    Schalter["a"] = 1
    Schalter["b"] = 2

    aa, bb, cc, dd = foo(c=3, d=4)
    assert aa == 1 and bb == 2
Пример #11
0
def test_multiple_prefixes():
    Schalter.clear()

    Schalter["first/second/leaf_a"] = 8
    Schalter["first/second/leaf_b"] = "foo"

    @Schalter.prefix("first")
    @Schalter.prefix("second")
    @Schalter.configure
    def foo(_unused, *, leaf_a, leaf_b):
        return _unused, leaf_a, leaf_b

    with pytest.raises(TypeError):
        _ = foo()

    assert foo(None) == (None, 8, "foo")
Пример #12
0
def test_value_change():
    Schalter.clear()

    Schalter["x"] = 1
    Schalter["y"] = 2

    @Schalter.configure(a="x")
    @Schalter.configure(b="y")
    def foo(*, a, b):
        return a + b

    assert foo() == 3
    Schalter["x"] = 3
    assert foo() == 2 + 3
    Schalter["y"] = 7
    assert foo() == 3 + 7
Пример #13
0
def test_scope():
    Schalter.clear()

    @Schalter.scoped_configure
    def foo(*, a):
        return a

    with Schalter.Scope("A") as config_scope:
        foo(a=3)
        assert config_scope.fullname == "A"

    with Schalter.Scope("B") as config_scope:
        foo(a=4)
        assert config_scope.fullname == "B"

    assert Schalter["A/a"] == 3
    assert Schalter["B/a"] == 4
Пример #14
0
def test_empty_configures(caplog):
    Schalter.clear()

    # should issue a warning
    @Schalter.configure()
    def empty():
        pass

    assert "WARNING" in caplog.text
    assert caplog.records
    caplog.clear()

    @Schalter.configure()
    def empty(*_args):
        pass

    assert "WARNING" in caplog.text
    assert caplog.records
    caplog.clear()
Пример #15
0
def test_broad_and_narrow_configures():
    Schalter.clear()

    @Schalter.configure
    @Schalter.configure("b")
    def foo(*, a, b):
        return a + b

    @Schalter.configure
    @Schalter.configure(d="a", c="b")
    def bar(*, c, d):
        return c, d

    Schalter["a"] = 1
    Schalter["b"] = 2
    Schalter["c"] = 3

    assert foo() == 3
    assert bar() == (2, 1)
Пример #16
0
def test_contradicting_remap(caplog):
    Schalter.clear()

    Schalter["x"] = "x"
    Schalter["y"] = "y"

    @Schalter.configure(a="x")
    @Schalter.configure(a="y")
    def foo(*, a):
        return a

    # expecting a warning
    assert "WARNING" in caplog.text
    assert caplog.records
    caplog.clear()

    # the mapping is expected to point to "y" config entry
    assert foo() == "y"

    # this does not warn, because the mapping target is identical.
    @Schalter.configure
    @Schalter.configure("a")
    def bar(*, a):
        return a

    assert not caplog.text
    assert not caplog.records
    caplog.clear()

    # this warns for two remaps.
    @Schalter.configure
    @Schalter.configure(a="y")
    @Schalter.configure("a", b="y")
    def bar(*, a, b):
        return a, b

    # expecting a warning
    assert "WARNING" in caplog.text
    assert len(caplog.records) == 2
    caplog.clear()
Пример #17
0
def test_multiple_default_values():
    Schalter.clear()

    with pytest.raises(ValueError):

        @Schalter.configure
        def add_constant_a(x: int, *, constant_value: int = 1):
            return x + constant_value

        @Schalter.configure
        def add_constant_b(x: int, *, constant_value: int = 2):
            return x + constant_value

    assert Schalter["constant_value"] == 1

    @Schalter.configure
    def add_constant_c(x: int, *, constant_value: int = 1):
        return x + constant_value

    Schalter.clear()

    @Schalter.configure
    def foo(*, _name: str = "baz"):
        pass

    @Schalter.configure
    def bar(*, _name: str = "baz"):
        pass

    with pytest.raises(ValueError):

        @Schalter.configure
        def foo(*, _name2: str = "baz"):
            pass

        @Schalter.configure
        def bar(*, _name2: str = "bar"):
            pass
Пример #18
0
def test_remap_key():
    Schalter.clear()

    @Schalter.configure(local_name="config_name")
    def f(*, local_name: str = "default_value"):
        print(local_name)

    assert Schalter["config_name"] == "default_value"

    @Schalter.configure("foo", bar="baz")
    def x(*, foo: int = 3, bar: int = 5):
        _ = foo * bar

    assert Schalter["foo"] == 3
    assert Schalter["baz"] == 5
    with pytest.raises(KeyError):
        _ = Schalter["bar"]

    @Schalter.configure(foo="bar", bar="foo")
    def y_swap(*, foo, bar):
        return foo, bar

    assert y_swap(foo=42) == (42, 3)
Пример #19
0
def test_schalter():
    Schalter.clear()

    @Schalter.configure
    def add_constant(x: int, *, constant_value: int = 1):
        return x + constant_value

    assert Schalter["constant_value"] == 1

    assert add_constant(1) == 2
    assert Schalter["constant_value"] == 1

    assert add_constant(1, constant_value=3) == 4
    assert Schalter["constant_value"] == 3

    Schalter["another_value"] = 42

    @Schalter.configure
    def check_value(expected, *, another_value: int = -1):
        assert expected == another_value

    check_value(42)
    check_value(1, another_value=1)
    check_value(1)
Пример #20
0
def schalter_object_cleared():
    Schalter.clear()
    return Schalter