Metadata-Version: 2.1
Name: argparse-deco
Version: 0.5.2
Summary: argparse-deco - Syntactic sugar for argparse
Home-page: https://github.com/zaehlwerk/argparse-deco
Author: Gregor Giesen
Author-email: giesen@zaehlwerk.net
License: GPLv3
Description: =============
        argparse-deco
        =============
        
        argparse-deco is basically syntatic sugar for argparse using
        decorators. Although it inherited some ideas and concepts from
        Kevin L. Mitchell's **cli_tools**
        (https://github.com/klmitch/cli_tools), it does not share its source
        code.
        
        Its main difference is the possibility to abuse Python's class
        syntax to define complex CLI tools with nested subcommands and
        the use of `inspect.signature` to autogenerate a command's arguments
        from a function's signature.
        
        Simple CLI
        ==========
        
        The API suffices to use three imports.
        
        >>> from argparse_deco import CLI, Arg, Flag
        
        An an example for a simple CLI, one may use `CLI` as decorator for a
        function in order to transform it:
        
        >>> @CLI(prog="prog")
        ... def prog(
        ...         integers: Arg(metavar='N', nargs='+', type=int,
        ...                       help="an integerfor the accumulator"),
        ...         accumulate: Arg('--sum', action='store_const', const=sum,
        ...                         help="sum the integers (default: find the max)"
        ...                         )=max):
        ...     """Process some integers."""
        ...     print(accumulate(integers))
        
        The decorator `CLI` transforms the function `prog` into an `Command`
        instance. Effectively `prog` takes some command line argument like
        `[ "1", "2", "4", "--sum" ]` as `cli_args` keyword, which is transformed
        by the `argparse` module into arguments `integer` and `accumulate`
        passed down to the original function `prog`:
        
        >>> prog(["1", "2", "4", "--sum"])
        7
        >>> prog(["1", "2", "4"])
        4
        
        In order to obtain the `ArgumentParser` instance, `prog` has the class
        method `setup_parser`:
        
        >>> parser = prog.setup_parser()
        >>> print(parser)
        ArgumentParser(prog='prog', usage=None, description='Process some integers.', formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
        >>> parser.print_usage()
        usage: prog [-h] [--sum] N [N ...]
        
        >>> parser.print_help()
        usage: prog [-h] [--sum] N [N ...]
        <BLANKLINE>
        Process some integers.
        <BLANKLINE>
        positional arguments:
          N           an integerfor the accumulator
        <BLANKLINE>
        optional arguments:
          -h, --help  show this help message and exit
          --sum       sum the integers (default: find the max)
        
        
        Arguments
        ---------
        
        In order for a function's arguments to be processed as
        `ArgumentParser` argument, they have to annotated by `Arg`. Basically
        `Arg` allows a the type as keyword, and arbitrary keyword arguments
        which are passed almost unchanged to `ArgumentParser.add_argument`.
        
        
        Parser
        ------
        
        While the `ArgumentParser` instance's `description` is usually the
        function's docstring, one may want to further customise it using the
        `CLI.parser` decorator which accepts any argument `ArgumentParser`
        would.
        
        
        Groups
        ------
        
        Arguments can be groupsed by using the `Group` instead of `Arg` in the
        argument's annotation, which accepts a group name as first keyword and
        the type as second one. The group can be customised (title,
        description) using the `CLI.group` decorator:
        
        >>> @CLI("prog")
        ... @CLI.group('foo', title="Foo", description="Foo group")
        ... def prog(
        ...         bar: Arg['foo'](help="Bar option"),
        ...         baz: Arg['foo'](help="Baz option")):
        ...     pass
        >>> prog.setup_parser().print_help()
        usage: prog [-h] bar baz
        <BLANKLINE>
        optional arguments:
          -h, --help  show this help message and exit
        <BLANKLINE>
        Foo:
          Foo group
        <BLANKLINE>
          bar         Bar option
          baz         Baz option
        
        Similarily using the `CLI.mutually_exclusive` decorator, arguments can
        be turned into a mutually exclusive group.
        
        
        Subcommands
        ===========
        
        >>> @CLI("prog")
        ... @CLI.subparsers(help="sub-command help")
        ... class prog:
        ...     def __call__(foo: Flag('--foo', help="foo help")):
        ...         pass
        ...     def a(bar: Arg(type=int, help="bar help")):
        ...         """a help"""
        ...     def b(baz: Arg('--baz', choices='XYZ', help="baz help")):
        ...         """b help"""
        >>> prog.parser.print_help()
        usage: prog [-h] [--foo] {a,b} ...
        <BLANKLINE>
        positional arguments:
          {a,b}       sub-command help
            a         a help
            b         b help
        <BLANKLINE>
        optional arguments:
          -h, --help  show this help message and exit
          --foo       foo help
        
        >>> prog.parser.parse_args(['a', '12'])
        Namespace(_func=<function prog.a at 0x...>, _parser=..., bar=12, foo=False)
        >>> prog.parser.parse_args(['--foo', 'b', '--baz', 'Z'])
        Namespace(_func=<function prog.b at 0x...>, _parser=..., baz='Z', foo=True)
        
        Deeper levels of subcommands can be generated using class definitions within:
        
        >>> @CLI("prog")
        ... class prog:
        ...     class foo:
        ...         """foo subcommand"""
        ...         def bar():
        ...             """foo bar subsubcommand"""
        ...         def baz():
        ...             """foo baz subsubcommand"""
        ...     class oof:
        ...         def rab():
        ...             """oof rab subsubcommand"""
        ...         def zab():
        ...             """oof zab subsubcommand"""
        >>> prog.parser.print_help()
        usage: prog [-h] {foo,oof} ...
        <BLANKLINE>
        positional arguments:
          {foo,oof}
            foo       foo subcommand
        <BLANKLINE>
        optional arguments:
          -h, --help  show this help message and exit
        
Keywords: cli
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Provides-Extra: test
