import sys from genbu import Genbu, Param, combinators as comb, infer_parser, usage def hello(*names: str, greeting: str = "Hello") -> str: """Say hello.""" if not names: names = ("stranger",) return "{}, {}!".format(greeting, ", ".join(names)) cli = Genbu( hello, params=[ Param("greeting", ["-g", "--greeting"], comb.One(str)), Param("names", parser=infer_parser(tuple[str, ...])), Param( "help_", ["-?", "-h", "--help"], comb.Emit(True), aggregator=lambda _: sys.exit(usage(cli)) ), ], ) if __name__ == "__main__": print(cli.run())
from pathlib import Path import sys from genbu import Genbu, Param, combinators as comb, usage def cat(path: Path) -> str: """Concatenate contents of path to stdout.""" return path.read_text() cli = Genbu( cat, params=[ Param("path", ["-p", "--path"], comb.One(Path)), Param( "help_", ["-?", "-h", "--help"], comb.Emit(True), aggregator=lambda _: sys.exit(usage(cli)), ), ], ) if __name__ == "__main__": try: print(cli.run()) except Exception as exc: name = " ".join(cli.complete_name()) print(f"{name}: {exc}\nTry '{name} -h' for more information.")
def test_or_parse_valid(source: str, expected: t.Any) -> None: """Or(f, g, ...) parser should match first valid input.""" parse = comb.Or(comb.One(int), comb.One(float), comb.One(str)) assert parse(as_tokens(source)).value == expected
def test_nan() -> None: """One(float) should parse nan.""" parser = comb.One(float) result = parser(collections.deque(["nan"])) assert math.isnan(result.value)
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."
from hypothesis import given, strategies as st import pytest from genbu import combinators as comb def as_tokens(source: t.Union[str, t.Iterable[str]]) -> comb.Tokens: """Convert source into Tokens.""" if isinstance(source, str): source = shlex.split(source) return collections.deque(source) @pytest.mark.parametrize("parse,source,expected", [ (comb.One(int), "50", 50), (comb.One(int), "-123 2", -123), (comb.One(float), "-123.2", -123.2), (comb.One(str), "hello", "hello"), ]) def test_one_parse_valid( parse: comb.Parser, source: str, expected: int, ) -> None: """One(f) parser must consume one f from the input.""" assert parse(as_tokens(source)).value == expected @pytest.mark.parametrize("parse,source", [ (comb.One(int), []),
"""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())