Ejemplo n.º 1
0
def test_union():
    def f(xx: Union[int, float]):
        ...

    parser = func_argparser(f)
    check(parser, ["--xx", "3"], dict(xx=3))
    check(parser, ["--x", "3.1"], dict(xx=3.1))
    check_fail(
        parser,
        ["-x", "foo"],
        "argument -x/--xx: invalid Union[int, float] value: 'foo'",
    )

    def g(xx: Union[str, int]):
        ...

    parser = func_argparser(g)
    check(parser, ["--xx", "foo"], dict(xx="foo"))
    # Union types are tried in the order they are specified
    check(parser, ["--xx", "3"], dict(xx="3"))

    class Color(enum.Enum):
        RED = 1

    def h(xx: Union[int, Color, str]):
        ...

    parser = func_argparser(h)
    check(parser, ["--xx", "3"], dict(xx=3))
    check(parser, ["--xx", "red"], dict(xx=Color.RED))
    check(parser, ["--xx", "foo"], dict(xx="foo"))
Ejemplo n.º 2
0
def test_flag_collision():
    def f(xx: int, xxx: int = 1):
        ...

    parser = func_argparser(f)
    check(parser, ["--xx", "1"], dict(xx=1, xxx=1))
    check(parser, ["--xx", "1", "--xxx", "-3"], dict(xx=1, xxx=-3))
    check(parser, ["-x", "3"], dict(xx=3, xxx=1))

    def g(xx: int = 0, x: int = 1):
        ...

    parser = func_argparser(g)
    check(parser, ["--xx", "1"], dict(xx=1, x=1))
    check(parser, ["--xx", "1", "--x", "-3"], dict(xx=1, x=-3))
    check(parser, ["--xx", "1", "-x", "-3"], dict(xx=1, x=-3))
    check(parser, ["--x", "3"], dict(xx=0, x=3))
    check(parser, ["-x", "3"], dict(xx=0, x=3))

    # --hh could collide with -h/--help
    def h(hh: int = 0):
        ...

    parser = func_argparser(h)
    check(parser, ["--hh", "1"], dict(hh=1))
    with pytest.raises(SystemExit):
        # This is actually showing the help
        parser.parse_args(["-h", "1"])
Ejemplo n.º 3
0
def test_help(capsys):
    def f(xx: int, yy: int = 1):
        """Awesome documentation.

        xx should be an int
        yy: the y coordinate
        """
        ...

    func_argparser(f).print_help()
    out = capsys.readouterr().out
    assert "Awesome documentation." in out
    assert "the y coordinate (default=1)" in out
Ejemplo n.º 4
0
def test_optional():
    def f(xx: str = None):
        ...

    parser = func_argparser(f)
    check(parser, [], dict(xx=None))
    check(parser, ["--xx", "foo"], dict(xx="foo"))

    def g(xx: Optional[str]):
        ...

    parser = func_argparser(g)
    check(parser, [], dict(xx=None))
    check(parser, ["--xx", "foo"], dict(xx="foo"))
Ejemplo n.º 5
0
def test_help_bool_flag(capsys):
    def f(xx: bool = False, yy: bool = True):
        """Awesome documentation.

        xx: use some xx
        yy: use some yy
        """
        ...

    func_argparser(f).print_help()
    out = capsys.readouterr().out
    assert "Awesome documentation." in out
    assert "use some xx (default=False)" in out
    assert "use some yy (default=True, --no-yy to disable)" in out
Ejemplo n.º 6
0
def test_multi_with_override() -> None:
    def f(xx: int) -> None:
        ...

    def g(xx: bool, yy: bool = False) -> int:
        ...

    f_parser = func_argparser(f)
    f_parser.add_argument("--config", type=str, default="foo")
    parser = multi_argparser(f, g)
    parser = multi_argparser(foo=f_parser, bar=func_argparser(g))
    check(parser, "foo --xx 1", dict(__command=f, xx=1, config="foo"))
    check(parser, "foo -x 2 --config bar", dict(__command=f, xx=2, config="bar"))
    check(parser, "bar --xx", dict(__command=g, xx=True, yy=False))
Ejemplo n.º 7
0
def test_return_type():
    def f(xx: int, yy: int = 1) -> int:
        ...

    parser = func_argparser(f)
    check(parser, ["--xx", "1"], dict(xx=1, yy=1))
    check(parser, ["-x", "1", "-y", "-3"], dict(xx=1, yy=-3))
    check_fail(parser, ["-x", "foo"], "argument -x/--xx: invalid int value: 'foo'")
Ejemplo n.º 8
0
def test_int_flag():
    def f(xx: int, yy: int = 1):
        ...

    parser = func_argparser(f)
    check(parser, ["--xx", "1"], dict(xx=1, yy=1))
    check(parser, ["--xx", "1", "--yy", "-3"], dict(xx=1, yy=-3))
    check(parser, ["-x", "1", "-y", "-3"], dict(xx=1, yy=-3))
    check_fail(parser, ["-x", "foo"], "argument -x/--xx: invalid int value: 'foo'")
    check_fail(parser, ["-y", "1"], "the following arguments are required: -x/--xx")
Ejemplo n.º 9
0
def get_main_parser() -> ArgumentParser:
    # Generates the 'main' parser by patching a 'Config' parser
    p = func_argparse.func_argparser(Config)

    # Override defaults value to None, so we know what was set by the user.
    # Note that it will keep the original default values in the help message.
    p.set_defaults(**{f: None for f in Config._fields})
    p.add_argument("--config", type=str, default="base")
    p.set_defaults(__command=main)
    return p
Ejemplo n.º 10
0
def test_bool_flag():
    def f(xx: bool, yy: bool = True, zz: bool = False):
        ...

    parser = func_argparser(f)
    check(parser, [], dict(xx=False, yy=True, zz=False))
    check(parser, ["--xx", "--yy"], dict(xx=True, yy=True, zz=False))
    check(parser, ["--xx", "--yy", "--zz"], dict(xx=True, yy=True, zz=True))
    check(parser, ["-x", "-y", "-z"], dict(xx=True, yy=True, zz=True))
    check(parser, ["-x", "--no-y", "-z"], dict(xx=True, yy=False, zz=True))
    check(parser, ["--no-x", "--no-y", "--no-z"], dict(xx=False, yy=False, zz=False))
    check(parser, ["--no-y"], dict(xx=False, yy=False, zz=False))
Ejemplo n.º 11
0
def test_named_tuple_parser(capsys):
    class Foo(NamedTuple):
        """Foo documentation"""

        xx: int

    parser = func_argparser(Foo)
    check(parser, ["--xx", "3"], dict(xx=3))

    parser.print_help()
    out = capsys.readouterr().out
    # Prefer Foo documentation over default one
    assert "Foo documentation" in out
Ejemplo n.º 12
0
def test_override_required():
    def f(xx: int, yy: int = 1):
        ...

    parser = func_argparser(f)
    check_fail(parser, [], "the following arguments are required: -x/--xx")
    check_fail(parser, ["--yy", "3"], "the following arguments are required: -x/--xx")

    override(parser, "xx", default=2)
    override(parser, "yy", required=True)

    check_fail(parser, [], "the following arguments are required: -y/--yy")
    check(parser, ["--yy", "3"], dict(xx=2, yy=3))
Ejemplo n.º 13
0
def test_list():
    def f(xx: List[int]):
        ...

    parser = func_argparser(f)
    check(parser, ["--xx", "1", "--xx", "2", "--xx", "3"], dict(xx=[1, 2, 3]))
    check(parser, ["--xx", "1", "-x", "2", "--xx", "3"], dict(xx=[1, 2, 3]))
    check_fail(parser, [], "the following arguments are required: -x/--xx")

    def g(xx: List[int] = []):
        ...

    parser = func_argparser(g)
    check(parser, ["--xx", "1", "--xx", "2", "--xx", "3"], dict(xx=[1, 2, 3]))
    check(parser, ["--xx", "1", "-x", "2", "--xx", "3"], dict(xx=[1, 2, 3]))
    check(parser, [], dict(xx=[]))

    # Also works with Sequence.
    def h(xx: Sequence[int] = []):
        ...

    parser = func_argparser(h)
    check(parser, ["--xx", "1", "--xx", "2", "--xx", "3"], dict(xx=[1, 2, 3]))
Ejemplo n.º 14
0
def test_enum():
    class Color(enum.Enum):
        RED = 1
        GREEN = 2
        BLUE = 3

    def f(color: Color):
        ...

    parser = func_argparser(f)
    check(parser, ["--color", "RED"], dict(color=Color.RED))
    check(parser, ["-c", "BLUE"], dict(color=Color.BLUE))
    check(parser, ["-c", "blue"], dict(color=Color.BLUE))
    check_fail(parser, ["-c", "xx"], "argument -c/--color: invalid choice: 'xx'")
Ejemplo n.º 15
0
def get_main_parser(subparsers) -> ArgumentParser:
    p: Optional[ArgumentParser] = None
    if subparsers is not None:
        documentation = Config.__doc__.strip().split("\n")[0]
        p = subparsers.add_parser("mine", help=documentation)
        assert p is not None
        p.set_defaults(__command=main)
    p = func_argparse.func_argparser(Config, p)
    p.add_argument("--config", type=str, default="base")

    # Override defaults value to None, so we know what was set by the user.
    # Note that it will keep the original default values in the help message.
    p.set_defaults(**{f: None for f in Config._fields})
    return p
Ejemplo n.º 16
0
def test_class_parser(capsys):
    class Foo:
        """Foo documentation"""

        def __init__(self, xx: int):
            """__init__ documentation"""
            self.xx = xx

    parser = func_argparser(Foo)
    check(parser, ["--xx", "3"], dict(xx=3))

    parser.print_help()
    out = capsys.readouterr().out
    # Prefer __init__ documentation over Foo ones
    assert "__init__ documentation" in out
Ejemplo n.º 17
0
def test_override_type():
    def f(xx: int = 0xFFF):
        ...

    parser = func_argparser(f)
    check_fail(
        parser, ["--xx", "0xF00"], "argument -x/--xx: invalid int value: '0xF00'"
    )

    override(parser, "xx", type=lambda x: int(x, 0))
    check(parser, ["--xx", "0xF00"], dict(xx=0xF00))

    # overriding is reversible
    override(parser, "xx", type=int)
    check(parser, ["--xx", "0"], dict(xx=0))
Ejemplo n.º 18
0
def test_override_choice():
    def f(xx: str):
        assert xx in ("foo", "foobar", "bar")

    parser = func_argparser(f)
    check(parser, ["--xx", "bar"], dict(xx="bar"))
    check(parser, ["--xx", "baz"], dict(xx="baz"))

    override(parser, "xx", choices=("foo", "foobar", "bar"))
    check(parser, ["--xx", "bar"], dict(xx="bar"))
    check_fail(
        parser,
        ["--xx", "baz"],
        "invalid choice: 'baz' (choose from 'foo', 'foobar', 'bar')",
    )
Ejemplo n.º 19
0
def main():
    parser = func_argparse.multi_argparser(
        mine=cc_net.mine.get_main_parser(),
        reproduce=func_argparse.func_argparser(cc_net.minify.reproduce),
    )
    func_argparse.parse_and_call(parser)