Example #1
0
def test_cli_run_with_various_parameter_kinds_in_callback() -> None:
    """CLI arguments should properly be bound to callback params.

    Tested parameter kinds:
    - positional only
    - var positional
    - keyword only
    - var keyword
    """
    def callback(a: int, *b: int, c: int, **d: int) -> t.Any:
        return a, b, c, d

    cli = make_cli(
        params=[
            Param("a", ["-a"], parser=comb.One(int)),
            Param("b", ["-b"], parser=comb.Repeat(comb.One(int))),
            Param("c", ["-c"], parser=comb.One(int)),
            Param("d", ["-d"],
                  parser=comb.Repeat(
                      comb.And(comb.One(str), comb.One(int)),
                      then=dict,
                  )),
        ],
        callback=callback,
    )

    assert cli.run("-a 1 -b 2 -c 3 -d k 4".split()) == (1, (2, ), 3, {"k": 4})
    assert cli.run("-a 1 -c 2".split()) == (1, (), 2, {})
Example #2
0
def test_usage_with_custom_arg_descriptions() -> None:
    """usage(...) should use custom description instead of default one."""
    cli = Genbu(
        name="test-cli",
        description="Test Genbu",
        params=[
            Param("default", ["-a"], parser=comb.Repeat(comb.One(int))),
            Param(
                "custom",
                ["-b"],
                parser=comb.Repeat(comb.One(int)),
                arg_description="custom-arg-description",
            )
        ],
        callback=callback,
    )
    assert usage(cli) == """usage:  test-cli [options]
Example #3
0
def test_cli_run_with_arguments() -> None:
    """Test with positional arguments."""
    cli = make_cli(
        params=[Param("numbers", parser=comb.Repeat(comb.One(float)))],
        callback=lambda numbers: sum(numbers)  # pylint: disable=W0108
    )
    assert cli.run([]) == 0
    assert cli.run(["1.5", "2"]) == 3.5
    assert cli.run(["0.45e-5"]) == 0.45e-5
Example #4
0
def test_cli_run_without_arguments(argv: t.List[str]) -> None:
    """It should use sys.argv[1:]."""
    with pytest.MonkeyPatch.context() as mp:
        mp.setattr(sys, "argv", argv)
        cli = make_cli(
            params=[
                Param("arg", parser=comb.Repeat(comb.One(str), then=list)),
            ],
            callback=lambda arg: arg,
        )
        assert cli.run() == argv[1:]
Example #5
0
def test_repeat_parse_infinite() -> None:
    """Repeat(p) parser should break out of infinite loop.

    Ex: Emit always parses successfully, so Repeat(Emit(...)) would keep
    parsing forever if it doesn't break out of the loop.
    """
    parse = comb.Repeat(comb.Emit(True))

    tokens = as_tokens("1 2 3 4 5")
    before = tuple(tokens)
    result = parse(tokens)
    after = tuple(tokens)

    assert before == after == ("1", "2", "3", "4", "5")
    assert result.value == [True]
Example #6
0
def test_parser_pretty() -> None:
    """Parser.pretty should use template."""
    assert comb.Repeat(comb.One(int)).pretty() == "<[int...]>"

    parser = comb.And(comb.Or(comb.One(float), comb.Emit(False)))
    assert parser.pretty("test: {}, bye.") == "test: [float], bye."
Example #7
0
    """And(f, g, ...) parser should parse space separated list."""
    assert parse(as_tokens(source)).value == expected


@pytest.mark.parametrize("source,parse", [
    ("1.5", comb.And(comb.One(int))),
    ("hello 5.6", comb.And(comb.One(str), comb.One(int))),
])
def test_and_parse_invalid(source: str, parse: comb.Parser) -> None:
    """And(f, g, ...) parser should raise CantParse."""
    with pytest.raises(comb.CantParse):
        parse(as_tokens(source))


@pytest.mark.parametrize("source,expected,parse", [
    ("", [], comb.Repeat(comb.One(float), then=list)),
    ("ok", (), comb.Repeat(comb.One(float), then=tuple)),
    ("5 5 5 5 stop", 20, comb.Repeat(comb.One(int), then=sum)),
])
def test_repeat_parse_valid(
    source: str,
    expected: t.Any,
    parse: comb.Parser,
) -> None:
    """Repeat(p) parser should run p parser as many times as needed."""
    assert parse(as_tokens(source)).value == expected


@pytest.mark.parametrize("source,parse", [
    ("a", comb.Repeat(comb.One(int))),
    ("1.5", comb.Repeat(comb.One(int))),
Example #8
0
"""Add items."""

import sys

from genbu import Genbu, Param, combinators as comb, usage


def add(*args: float) -> float:
    """Add items."""
    return sum(args)


cli = Genbu(
    add,
    params=[
        Param("args", parser=comb.Repeat(comb.One(float))),
        Param(
            "_",
            ["-?", "-h", "-H"],
            description="Show help message",
            parser=comb.Emit(True),
            aggregator=lambda _: sys.exit(usage(cli)),
        ),
    ],
)

if __name__ == "__main__":
    print(cli.run())