Reference
Arger
Contains one (parser) or more commands (subparsers).
__init__(self, func=None, version=None, sub_parser_title='commands', formatter_class=<class 'argparse.ArgumentDefaultsHelpFormatter'>, exceptions_to_catch=(), _doc_str=None, _level=0, **kwargs)
special
Parameters:
Name | Type | Description | Default |
---|---|---|---|
func |
Optional[Callable] |
A callable to parse root parser's arguments. |
None |
version |
Optional[str] |
adds --version flag. |
None |
sub_parser_title |
sub-parser title to pass. |
'commands' |
|
exceptions_to_catch |
Sequence[Type[Exception]] |
exceptions to catch and print its message. Will exit with 1 and will hide traceback. |
() |
_doc_str |
Optional[arger.docstring.DocstringTp] |
internally passed from arger.add_cmd |
None |
_level |
internal |
0 |
|
**kwargs |
all the arguments that are supported by ArgumentParser |
{} |
Examples:
adding version flag version = '%(prog)s 2.0' Arger() equals to Arger().add_argument('--version', action='version', version=version)
Source code in arger/main.py
def __init__(
self,
func: tp.Optional[tp.Callable] = None,
version: tp.Optional[str] = None,
sub_parser_title="commands",
formatter_class=ap.ArgumentDefaultsHelpFormatter,
exceptions_to_catch: tp.Sequence[tp.Type[Exception]] = (),
_doc_str: tp.Optional[DocstringTp] = None,
_level=0,
**kwargs,
):
"""
Args:
func: A callable to parse root parser's arguments.
version: adds --version flag.
sub_parser_title: sub-parser title to pass.
exceptions_to_catch: exceptions to catch and print its message.
Will exit with 1 and will hide traceback.
_doc_str: internally passed from arger.add_cmd
_level: internal
**kwargs: all the arguments that are supported by
[ArgumentParser](https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser)
Examples:
adding version flag
version = '%(prog)s 2.0'
Arger() equals to Arger().add_argument('--version', action='version', version=version)
"""
kwargs.setdefault("formatter_class", formatter_class)
self.sub_parser_title = sub_parser_title
self.sub_parser: tp.Optional[ap._SubParsersAction] = None
self.args: tp.Dict[str, Argument] = OrderedDict()
docstr = DocstringParser.parse(func) if _doc_str is None else _doc_str
kwargs.setdefault("description", docstr.description)
kwargs.setdefault("epilog", docstr.epilog)
super().__init__(**kwargs)
self.set_defaults(**{LEVEL: _level})
self.func = func
self.exceptions_to_catch = exceptions_to_catch
self._add_arguments(docstr, _level)
if version:
self.add_argument("--version", action="version", version=version)
add_cmd(self, func=None, **kwargs)
Create a sub-command from the function. All its parameters will be converted to CLI args wrt their types.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
func |
function to create sub-command from. |
None |
|
**kwargs |
will get passed to |
{} |
Returns Arger: A new parser from the function is returned.
Source code in arger/main.py
def add_cmd(self, func=None, **kwargs):
"""Create a sub-command from the function.
All its parameters will be converted to CLI args wrt their types.
Args:
func: function to create sub-command from.
**kwargs: will get passed to `subparser.add_parser` method
Returns
Arger: A new parser from the function is returned.
"""
if not self.sub_parser:
self.sub_parser = self.add_subparsers(title=self.sub_parser_title)
def _wrapper(fn: tp.Callable) -> "Arger":
docstr = DocstringParser.parse(fn)
arger = self.sub_parser.add_parser( # type: ignore
name=kwargs.pop("name", fn.__name__),
help=kwargs.pop("help", docstr.description),
func=fn,
_doc_str=docstr,
_level=self.get_default(LEVEL) + 1,
**kwargs,
)
return tp.cast(Arger, arger)
if func is None:
return _wrapper
return _wrapper(func)
init(**kwargs)
classmethod
Create parser from function as a decorator.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
**kwargs |
will be passed to arger.Arger initialisation. |
{} |
Source code in arger/main.py
@classmethod
def init(cls, **kwargs) -> tp.Callable[[tp.Callable], "Arger"]:
"""Create parser from function as a decorator.
Args:
**kwargs: will be passed to arger.Arger initialisation.
"""
def _wrapper(fn: tp.Callable):
return cls(func=fn, **kwargs)
return _wrapper
run(self, *args, *, capture_sys=True, **kwargs)
Parse cli and dispatch functions.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
capture_sys |
whether to capture |
True |
|
*args |
str |
The arguments will be passed onto as |
() |
**kwargs |
will get passed to |
{} |
Source code in arger/main.py
def run(self, *args: str, capture_sys=True, **kwargs) -> ap.Namespace:
"""Parse cli and dispatch functions.
Args:
capture_sys: whether to capture `sys.argv` if `args` not passed. Useful during testing.
*args: The arguments will be passed onto as `self.parse_args(args)`.
**kwargs: will get passed to `parse_args` method
"""
if not args and capture_sys:
args = tuple(sys.argv[1:])
namespace = self.parse_args(args, **kwargs)
kwargs = vars(namespace)
kwargs[NS_PREFIX] = copy.copy(namespace)
kwargs["_arger_"] = self
# dispatch all functions as in hierarchy
for level in range(kwargs.get(LEVEL, 0) + 1):
func_name = f"{FUNC_PREFIX}{level}"
if func_name in kwargs:
kwargs[func_name](**kwargs)
return namespace
Argument
__init__(self, *, type=None, metavar=None, required=None, nargs=None, const=None, choices=None, action=None, flags=(), **kwargs)
special
Represent positional arguments to the command that are required by default. Analogous to ArgumentParser.add_argument
Parameters:
Name | Type | Description | Default |
---|---|---|---|
type |
Union[Callable[[str], ~T], argparse.FileType] |
The type to which the command-line argument should be converted. Got from annotation.
Use Argument class itself in case you want to pass variables to Ex: |
None |
metavar |
str |
A name for the argument in usage messages. |
None |
nargs |
Union[int, str] |
The number of command-line arguments that should be consumed. to be generated from the type-hint. Ex: types and how they are converted to nargs
Note: even though Tuple[str,...] doesn't mean one or more, it is just to make |
None |
const |
Any |
covered by type-hint and default value given |
None |
choices |
Iterable[Any] |
Use |
None |
action |
Union[str, Type[argparse.Action]] |
The basic type of action to be taken when this argument is encountered at the command line. |
None |
flags |
Sequence[str] |
It will be generated from the argument name. In case one wants to override the generated flags, could be done by passing them. |
() |
default |
tp.Any |
The value produced if the argument is absent from the command line.
|
required |
kwargs |
Any |
it is delegated to |
{} |
Source code in arger/main.py
def __init__(
self,
*,
type: tp.Union[tp.Callable[[str], tp_utils.T], ap.FileType] = None,
metavar: str = None,
required: bool = None,
nargs: tp.Union[int, str] = None,
const: tp.Any = None,
choices: tp.Iterable[tp.Any] = None,
action: tp.Union[str, tp.Type[ap.Action]] = None,
flags: tp.Sequence[str] = (),
**kwargs: tp.Any,
):
"""Represent positional arguments to the command that are required by default.
Analogous to
[ArgumentParser.add_argument](https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument)
Args:
type: The type to which the command-line argument should be converted.
Got from annotation.
Use Argument class itself in case you want to pass variables to `Arger.add_argument`.
Ex: `typing.cast(int, Argument(type=int))`. If not passed then it is returned as str.
metavar: A name for the argument in usage messages.
nargs: The number of command-line arguments that should be consumed.
to be generated from the type-hint.
Ex: types and how they are converted to nargs
* `Tuple[str, ...] -> nargs='+'`
* `Tuple[str, str] -> nargs=2`
* `List[str]|tuple|list -> nargs=*`
Note: even though Tuple[str,...] doesn't mean one or more, it is just to make `nargs=+` easier to add.
const: covered by type-hint and default value given
choices: Use `enum.Enum` as the typehint to generate choices automatically.
action: The basic type of action to be taken
when this argument is encountered at the command line.
flags: It will be generated from the argument name.
In case one wants to override the generated flags, could be done by passing them.
default (tp.Any): The value produced if the argument is absent from the command line.
* The default value assigned to a keyword argument helps determine
the type of option and action if it is not type annotated.
* The default value is assigned directly to the parser's default for that option.
* In addition, it determines the ArgumentParser action
* a default value of False implies store_true, while True implies store_false.
* If the default value is a list, the action is append
(multiple instances of that option are permitted).
* Strings or None imply a store action.
kwargs: it is delegated to `ArgumentParser.add_argument` method.
"""
for var_name in (
"type",
"metavar",
"required",
"nargs",
"const",
"choices",
"action",
):
value = locals()[var_name]
if value is not None:
kwargs[var_name] = value
self.flags = flags
self.kwargs = kwargs