Cli¶
Low-level interface to CLI parser.
Yuio’s primary interface for building CLIs is yuio.app; this is low-level module
that actually parses arguments. Because of this, yuio.cli doesn’t expose
a convenient interface for building CLIs. Instead, it exposes a set of classes
that describe an interface; yuio.app and yuio.config compose these
classes and pass them to CliParser.
This module is inspired by argparse, but there are differences:
all flags should start with
-, other symbols are not supported (at least for now);unlike
argparse, this module doesn’t rely on partial parsing and sub-parses. Instead, it operates like a regular state machine, and any unmatched flags or arguments are reported right away;it uses nested namespaces, one namespace per subcommand. When a subcommand is encountered, a new namespace is created and assigned to the corresponding
destin the parent namespace;namespaces are abstracted away by the
Namespaceprotocol, which has an interface similar todict;options from base command can be specified after a subcommand argument, unless subcommand shadows them. This is possible because we don’t do partial parsing.
For example, consider this program:
import argparse parser = argparse.ArgumentParser() parser.add_argument("-v", "--verbose", action="count") subparsers = parser.add_subparsers() subcommand = subparsers.add_parser("subcommand")
Argparse will not recognize
--verboseif it’s specified aftersubcommand, butyuio.clihandles this just fine:$ prog subcommand --verbose
there’s no distinction between
nargs=Noneandnargs=1; however, there is a distinction between argument being specified inline or not. This allows us to supply arguments for options withnargs=0.See Handling flags with optional values for details;
the above point also allows us to disambiguate positional arguments and arguments with
nargs="*":$ prog --array='a b c' subcommand
See Handling options with multiple values for details;
this parser tracks information about argument positions and offsets, allowing it to display rich error messages;
we expose more knobs to tweak help formatting; see functions on
Optionfor details.
Commands and sub-commands¶
- class yuio.cli.Command(
- *,
- name: str,
- desc: str,
- help: str | Disabled,
- epilog: str,
- usage: str,
- options: list[Option[Any]],
- subcommands: dict[str, Command[Namespace] | LazyCommand[Namespace]],
- subcommand_required: bool,
- ns_ctor: Callable[[], NamespaceT],
- dest: str,
- ns_dest: str,
- metavar: str = '<subcommand>',
Data about CLI interface of a single command or subcommand.
- help: str | Literal[_Placeholders.DISABLED]¶
Help message for this command, displayed when listing subcommands.
- subcommands: dict[str, Command[Namespace] | LazyCommand[Namespace]]¶
Last positional option can be a sub-command.
This is a map from subcommand’s name or alias to subcommand’s implementation.
- subcommand_required: bool¶
Whether subcommand is required or optional. If no
subcommandsare given, this attribute is ignored.
Flags and positionals¶
- class yuio.cli.Option(
- *,
- flags: list[str] | Positional,
- allow_inline_arg: bool,
- allow_implicit_inline_arg: bool,
- nargs: NArgs,
- allow_no_args: bool,
- required: bool,
- metavar: str | tuple[str, ...],
- mutex_group: None | MutuallyExclusiveGroup,
- usage: Collapse | bool,
- help: str | Disabled,
- help_group: HelpGroup | None,
- default_desc: str | None,
- show_if_inherited: bool,
- allow_abbrev: bool,
- dest: str,
Base class for a CLI option.
- flags: list[str] | yuio.Positional¶
Flags corresponding to this option. Positional options have flags set to
yuio.POSITIONAL.
- allow_inline_arg: bool¶
Whether to allow specifying argument inline (i.e.
--foo=bar).Inline arguments are handled separately from normal arguments, and
nargssetting does not affect them.Positional options can’t take inline arguments, so this attribute has no effect on them.
- allow_implicit_inline_arg: bool¶
Whether to allow specifying argument inline with short flags without equals sign (i.e.
-fValue).Inline arguments are handled separately from normal arguments, and
nargssetting does not affect them.Positional options can’t take inline arguments, so this attribute has no effect on them.
- required: bool¶
Makes this option required. The parsing will fail if this option is not encountered among CLI arguments.
Note that positional arguments are always parsed; if no positionals are given, all positional options are processed with zero arguments, at which point they’ll fail
nargscheck. Thus,requiredhas no effect on positionals.
- metavar: str | tuple[str, ...]¶
Option’s meta variable, used for displaying help messages.
If
nargsis an integer, this can be a tuple of strings, one for each argument. Ifnargsis zero, this can be an empty tuple.
- mutex_group: None | MutuallyExclusiveGroup¶
Mutually exclusive group for this option. Positional options can’t have mutex groups.
- usage: yuio.Collapse | bool¶
Specifies whether this option should be displayed in CLI usage. Positional options are always displayed, regardless of this setting.
- help: str | yuio.Disabled¶
Help message for an option.
- help_group: HelpGroup | None¶
Group for this flag, default is
OPTS_GROUPfor flags andARGS_GROUPfor positionals. Positionals are flags are never mixed together; if they appear in the same group, the group title will be repeated twice.
- show_if_inherited: bool¶
Force-show this flag if it’s inherited from parent command. Positionals can’t be inherited because subcommand argument always goes last.
- abstractmethod process(
- cli_parser: CliParser[Namespace],
- flag: Flag | None,
- arguments: Argument | list[Argument],
- ns: Namespace,
Process this argument.
This method is called every time an option is encountered on the command line. It should parse option’s args and merge them with previous values, if there are any.
When option’s arguments are passed separately (i.e.
--opt arg1 arg2 ...), args is given as a list. List’s length is checked againstnargsbefore this method is called.When option’s arguments are passed as an inline value (i.e.
--long=argor-Sarg), the args is given as a string.nargsare not checked in this case, giving you an opportunity to handle inline option however you like.- Parameters:
cli_parser – CLI parser instance that’s doing the parsing. Not to be confused with
yuio.parse.Parser.flag – flag that set this option. This will be set to
Nonefor positional arguments.arguments – option arguments, see above.
ns – namespace where parsed arguments should be stored.
- Raises:
- post_process( )¶
Called once at the end of parsing to post-process all arguments.
- Parameters:
cli_parser – CLI parser instance that’s doing the parsing. Not to be confused with
yuio.parse.Parser.arguments – option arguments that were ever passed to this option.
ns – namespace where parsed arguments should be stored.
- Raises:
- format_usage(
- ctx: ReprContext,
- /,
Allows customizing how this option looks in CLI usage.
- Parameters:
ctx – repr context for formatting help.
- Returns:
a string that will be used to represent this option in program’s usage section.
- format_metavar(
- ctx: ReprContext,
- /,
Allows customizing how this option looks in CLI help.
- Parameters:
ctx – repr context for formatting help.
- Returns:
a string that will be appended to the list of option’s flags to format an entry for this option in CLI help message.
- format_help_tail(
- ctx: ReprContext,
- /,
- *,
- all: bool = False,
Format additional content that will be added to the end of the help message, such as aliases, default value, etc.
- Parameters:
ctx – repr context for formatting help.
all – whether
--help=allwas specified.
- Returns:
a string that will be appended to the main help message.
- format_alias_flags(
- ctx: ReprContext,
- /,
- *,
- all: bool = False,
Format alias flags that weren’t included in
primary_short_flagandprimary_long_flags.- Parameters:
ctx – repr context for formatting help.
all – whether
--help=allwas specified.
- Returns:
a list of strings, one per each alias.
- format_default(
- ctx: ReprContext,
- /,
- *,
- all: bool = False,
Format default value that will be included in the CLI help.
- Parameters:
ctx – repr context for formatting help.
all – whether
--help=allwas specified.
- Returns:
a string that will be appended to the main help message.
- class yuio.cli.ValueOption(
- *,
- flags: list[str] | Positional,
- allow_inline_arg: bool,
- allow_implicit_inline_arg: bool,
- nargs: NArgs,
- allow_no_args: bool,
- required: bool,
- metavar: str | tuple[str, ...],
- mutex_group: None | MutuallyExclusiveGroup,
- usage: Collapse | bool,
- help: str | Disabled,
- help_group: HelpGroup | None,
- default_desc: str | None,
- show_if_inherited: bool,
- allow_abbrev: bool,
- dest: str,
- merge: Callable[[T, T], T] | None,
- default: object,
Base class for options that parse arguments and assign them to namespace.
This base handles assigning parsed value to the target destination and merging values if option is invoked multiple times. Call
self.set(ns, value)fromOption.process()to set result of option processing.
- class yuio.cli.ParserOption(
- *,
- flags: list[str] | Positional,
- allow_inline_arg: bool,
- allow_implicit_inline_arg: bool,
- nargs: NArgs,
- allow_no_args: bool,
- required: bool,
- metavar: str | tuple[str, ...],
- mutex_group: None | MutuallyExclusiveGroup,
- usage: Collapse | bool,
- help: str | Disabled,
- help_group: HelpGroup | None,
- default_desc: str | None,
- show_if_inherited: bool,
- allow_abbrev: bool,
- dest: str,
- merge: Callable[[T, T], T] | None,
- default: object,
- parser: Parser[T],
Base class for options that use
yuio.parseto process arguments.- parser: yuio.parse.Parser[T]¶
A parser used to parse option’s arguments.
- class yuio.cli.BoolOption(
- *,
- pos_flags: list[str],
- neg_flags: list[str],
- required: bool = False,
- mutex_group: None | MutuallyExclusiveGroup = None,
- usage: Collapse | bool = True,
- help: str | Disabled = '',
- help_group: HelpGroup | None = None,
- show_if_inherited: bool = False,
- dest: str,
- parser: Parser[bool] | None = None,
- merge: Callable[[bool, bool], bool] | None = None,
- default: bool | Missing = yuio.MISSING,
- allow_abbrev: bool = True,
- default_desc: str | None = None,
An option that combines
StoreTrueOption,StoreFalseOption, andParseOneOption.If any of the
pos_flagsare given without arguments, it works likeStoreTrueOption.If any of the
neg_flagsare given, it works likeStoreFalseOption.If any of the
pos_flagsare given with an inline argument, the argument is parsed as abool.Note
Bool option has
nargsset to0, so non-inline arguments (i.e.--json false) are not recognized. You should always use inline argument to set boolean flag’s value (i.e.--json=false). This avoids ambiguity in cases like the following:$ prog --json subcommand # Ok $ prog --json=true subcommand # Ok $ prog --json true subcommand # Not allowed
- Example:
option = yuio.cli.BoolOption( pos_flags=["--json"], neg_flags=["--no-json"], dest=..., )
$ prog --json # Set `dest` to `True` $ prog --no-json # Set `dest` to `False` $ prog --json=$value # Set `dest` to parsed `$value`
- class yuio.cli.ParseOneOption(
- *,
- flags: list[str] | Positional,
- required: bool = False,
- mutex_group: None | MutuallyExclusiveGroup = None,
- usage: Collapse | bool = True,
- help: str | Disabled = '',
- help_group: HelpGroup | None = None,
- show_if_inherited: bool = False,
- dest: str,
- parser: Parser[T],
- merge: Callable[[T, T], T] | None = None,
- default: T | Missing = yuio.MISSING,
- allow_abbrev: bool = True,
- default_desc: str | None = None,
An option with a single argument that uses Yuio parser.
- class yuio.cli.ParseManyOption(
- *,
- flags: list[str] | Positional,
- required: bool = False,
- mutex_group: None | MutuallyExclusiveGroup = None,
- usage: Collapse | bool = True,
- help: str | Disabled = '',
- help_group: HelpGroup | None = None,
- show_if_inherited: bool = False,
- dest: str,
- parser: Parser[T],
- merge: Callable[[T, T], T] | None = None,
- default: T | Missing = yuio.MISSING,
- allow_abbrev: bool = True,
- default_desc: str | None = None,
An option with multiple arguments that uses Yuio parser.
- class yuio.cli.StoreConstOption(
- *,
- flags: list[str],
- required: bool = False,
- mutex_group: None | MutuallyExclusiveGroup = None,
- usage: Collapse | bool = True,
- help: str | Disabled = '',
- help_group: HelpGroup | None = None,
- show_if_inherited: bool = False,
- dest: str,
- merge: Callable[[T, T], T] | None = None,
- default: T | Missing = yuio.MISSING,
- const: T,
- allow_abbrev: bool = True,
- default_desc: str | None = None,
An option with no arguments that stores a constant to namespace.
- const: T¶
Constant that will be stored.
- class yuio.cli.StoreFalseOption(
- *,
- flags: list[str],
- required: bool = False,
- mutex_group: None | MutuallyExclusiveGroup = None,
- usage: Collapse | bool = True,
- help: str | Disabled = '',
- help_group: HelpGroup | None = None,
- show_if_inherited: bool = False,
- dest: str,
- default: bool | Missing = yuio.MISSING,
- allow_abbrev: bool = True,
- default_desc: str | None = None,
An option that stores
Falseto namespace.
- class yuio.cli.StoreTrueOption(
- *,
- flags: list[str],
- required: bool = False,
- mutex_group: None | MutuallyExclusiveGroup = None,
- usage: Collapse | bool = True,
- help: str | Disabled = '',
- help_group: HelpGroup | None = None,
- show_if_inherited: bool = False,
- dest: str,
- default: bool | Missing = yuio.MISSING,
- allow_abbrev: bool = True,
- default_desc: str | None = None,
An option that stores
Trueto namespace.
- class yuio.cli.CountOption(
- *,
- flags: list[str],
- required: bool = False,
- mutex_group: None | MutuallyExclusiveGroup = None,
- usage: Collapse | bool = True,
- help: str | Disabled = '',
- help_group: HelpGroup | None = None,
- show_if_inherited: bool = False,
- dest: str,
- default: int | Missing = yuio.MISSING,
- allow_abbrev: bool = True,
- default_desc: str | None = None,
An option that counts number of its appearances on the command line.
- class yuio.cli.VersionOption(
- *,
- version: str,
- flags: list[str] = ['-V', '--version'],
- usage: Collapse | bool = yuio.COLLAPSE,
- help: str | Disabled = 'Print program version and exit.',
- help_group: HelpGroup | None = HelpGroup(title='Misc options', help='', collapse=False, _slug=None),
- allow_abbrev: bool = True,
An option that prints app’s version and stops the program.
- class yuio.cli.HelpOption(
- *,
- flags: list[str] = ['-h', '--help'],
- usage: Collapse | bool = yuio.COLLAPSE,
- help: str | Disabled = 'Print this message and exit.',
- help_group: HelpGroup | None = HelpGroup(title='Misc options', help='', collapse=False, _slug=None),
- allow_abbrev: bool = True,
An option that prints help message and stops the program.
Namespace¶
- class yuio.cli.Namespace(*args, **kwargs)¶
Protocol for namespace implementations.
CLI parser¶
- class yuio.cli.CliParser( )¶
CLI arguments parser.
- Parameters:
command – root command.
allow_abbrev – allow abbreviating CLI flags if that doesn’t create ambiguity.
help_parser – help parser that will be used to parse and display help for options that’ve failed to parse.
- class yuio.cli.Argument( )¶
Represents a CLI argument, or its part.
For positionals, this will contain the entire argument. For inline values, this will contain value substring and its position relative to the full value.
- Example:
Consider the following command arguments:
--arg=value
Argument
"value"will be represented as:Argument(value="value", index=0, pos=6, flag="--arg", metavar=...)
- index: int¶
Index of this argument in the array that was passed to
CliParser.parse().Note that this array does not include executable name, so indexes are shifted relative to
sys.argv.
- class yuio.cli.Flag(value: 'str', index: 'int')¶
-
- index: int¶
Index of this flag in the array that was passed to
CliParser.parse().Note that this array does not include executable name, so indexes are shifted relative to
sys.argv.
- class yuio.cli.ArgumentError(
- *args,
- flag: Flag | None = None,
- arguments: Argument | list[Argument] | None = None,
- n_arg: int | None = None,
- pos: tuple[int, int] | None = None,
- path: list[tuple[Any, str | None]] | None = None,
- option: Option[Any] | None = None,
Error that happened during argument parsing.
- flag: Flag | None¶
Flag that caused this error. Can be
Noneif error is caused by a positional argument.
- arguments: Argument | list[Argument] | None¶
Arguments that caused this error.
This can be a single argument, or multiple arguments. In the later case,
n_argshould correspond to the argument that failed to parse. Ifn_argisNone, then all arguments are treated as faulty.Note
Don’t confuse
argumentsandargs: the latter contains formatting arguments and is defined in theBaseExceptionclass.
- pos: tuple[int, int] | None¶
Position in the original string in which this error has occurred (start and end indices).
If
n_argis set, andargumentsis given as a list, then this position is relative to the argument at indexn_arg.If
argumentsis given as a single argument (not a list), then this position is relative to that argument.Otherwise, position is ignored.
- path: list[tuple[Any, str | None]] | None¶
Same as in
ParsingError.path. Can be present if parser usesparse_config()for validation.
Option grouping¶
- class yuio.cli.MutuallyExclusiveGroup(*, required: bool = False)¶
A sentinel for creating mutually exclusive groups.
Pass an instance of this class all
field()s that should be mutually exclusive.
- class yuio.cli.HelpGroup( )¶
Group of flags in CLI help.
- yuio.cli.ARGS_GROUP = HelpGroup(title='Arguments', help='', collapse=False, _slug=None)¶
Help group for positional arguments.
- yuio.cli.SUBCOMMANDS_GROUP = HelpGroup(title='Subcommands', help='', collapse=False, _slug=None)¶
Help group for subcommands.
- yuio.cli.OPTS_GROUP = HelpGroup(title='Options', help='', collapse=False, _slug=None)¶
Help group for flags.
- yuio.cli.MISC_GROUP = HelpGroup(title='Misc options', help='', collapse=False, _slug=None)¶
Help group for misc flags such as
--helpor--version.