argparseDecorator API

Module contents

class AppendAction(*args, **kwargs)

Bases: List[T]

Tells the ArgumentParser to append the command line value to a list.

With this annotation an argument can be specified multiple times on the command line.

@cli.command
def cmd(foo: Option | AppendAction | int)
    return foo

parser.execute("cmd --foo 1 --foo 2")  # returns [1, 2]

Internally this will add the action = "append" option to the argument.

See argparse: action for details.

class ArgParseDecorator(helpoption: Optional[str] = 'help', hyph_replace: str = '__', argparser_class: Optional[Type[ArgumentParser]] = None, **kwargs)

Bases: object

Build python argparse.ArgumentParser from decorated functions.

It uses the signature and the annotations of the decorated class to determine all arguments and their types. It also uses the docstring for the command description, the help strings for all arguments and some additional metadata that can not be expressed via annotations.

Parameters
  • helpoption

    Either

    • "help" to automatically create a help command, or

    • "-h" to automatically add a -h/--help argument to each command (argparse library default), or

    • None to disable any automatically generated help.

    Defaults to "help"

  • hyph_replace – string to be replaced by - in command names, defaults to __ (two underscores)

  • argparser_class (argparse.ArgumentParser or subclass thereof.) – Class to be used for ArgumentParser, defaults to NonExitingArgumentParser

  • kwargs – Other arguments to be passed to the ArgumentParser, e.g. description or allow_abbrev

add_argument(*args: str, **kwargs: Any) Callable

Decorator to add an argument to the command.

This is an alternative way to add arguments to a function. While its use is usually not required there might be some situations where the function signature and its annotations are not sufficient to accurately describe an argument. In this case the add_argument() decorator can be used. Any pararmeter to this decorator is passed directly to add_argument() method of the underlying ArgumentParser

The decorated function must have an argument of the same name or use *args and **kwargs arguments to retrieve the value of these arguments.

Example:

@parser.command
@parser.add_argument('dest_file', type=argparse.FileType('r', encoding='latin-1'))
@parser.add_argument('--foo', '-f')
def write(*args, **kwargs):
    dest_file = args[0]
    foo = kwargs['foo']
Parameters
  • args – Optional arguments that are passed directly to the ArgumentParser.add_argument() method.

  • kwargs – Optional keyword arguments that are passed directly to the ArgumentParser.add_argument() method.

Returns

The decorator function

property argumentparser: ArgumentParser

The generated argparse.ArgumentParser object.

This property is read only

command(*args: Union[str, Callable], **kwargs: Any) Callable

Decorator to mark a method as an executable command.

This takes the name of the decorated function and adds it to the internal command list. It also analyses the signature and the docstring of the decorated function to gather information about its arguments.

Parameters
  • args – Optional arguments that are passed directly to the add_subparsers() method of the underlying ArgumentParser.

  • kwargs – Optional keyword arguments that are passed directly to the add_subparsers() method of the underlying ArgumentParser.

Returns

The decorator function

property command_dict: Dict[str, Optional[Dict]]

Get a dictionary with all commands in a form suitable for the Python Prompt Toolkit autocompleter function.

See Nested completion for details.

Returns

dict

execute(commandline: ~typing.Union[str, ~typing.List[str], ~shlex.shlex], base: ~typing.Optional = None, error_handler=<function default_error_handler>, stdout: ~typing.TextIO = None, stderr: ~typing.TextIO = None, stdin: ~typing.TextIO = None) Optional

Parse a command line and execute it.

The command line can be a single string which will be split into command and argument tokens via the shlex.shlex lexer with default settings. If the default settings are not appropriate then this method will also accept a customized shlex object as commandline - or any other Iterator (which shlex is)

Alternatively commandline can also be a list of strings with the command name as the first item followed by subcommands and arguments. This can be used to process the command line arguments when called as a Python script by passing sys.argv as the commandline

Note

The base must be supplied if the method implementing the command is a bound method, i.e. having self as the first argument. It is not required if the command is implemented as a function (unbound) or an inner function (already bound).

Parameters
  • commandline

    Either a string with a command and arguments (e.g. "command --flag arg"),

    or a list of string elements (e.g. from sys.argv),

    or any Iterator supplying a list of tokens.

  • base – an object that is passed to the command function as the self argument. Required if any command method has self, not required otherwise.

  • error_handler

    callback function to handle errors when parsing the command line. The handler takes a single argument with a ArgumentError exception. The default is a function that just prints the error to stderr.

    If set to None parsing errors will result in an exception.

  • stdout

    Set to redirect the output of ArgumentParser (e.g. help texts) and the called command function to a different output, e.g. an ssh stream.

    Optional, default is sys.stdout

  • stderr

    Set to redirect error messages from the ArgumentParser and the called command function to a different output, e.g. an ssh stream.

    Optional, default is sys.stderr

  • stdin

    Set to redirect the input of the called command function to an input other than the current terminal, e.g. an ssh stream.

    Optional, default is sys.stdin

Returns

anything the command function/method returns.

Raises
  • ValueError – if the command function requires a self parameter, but no base argument was supplied.

  • ArgumentError – if the given command line contains errors and the error_handler is set to None.

async execute_async(commandline: ~typing.Union[str, ~typing.Iterator[str], ~typing.List[str]], base: ~typing.Optional = None, error_handler=<function default_error_handler>, stdout: ~typing.TextIO = None, stderr: ~typing.TextIO = None, stdin: ~typing.TextIO = None) Optional

Parse a command line and execute it in as an async coroutine.

The command line can be a single string which will be split into command and argument tokens via the shlex.shlex lexer with default settings. If the default settings are not appropriate then this method will also accept a customized shlex object as commandline - or any other Iterator (which shlex is)

Alternatively commandline can also be a list of strings with the command name as the first item followed by subcommands and arguments. This can be used to process the command line arguments when called as a Python script by passing sys.argv as the commandline

Note

The base must be supplied if the method implementing the command is a bound method, i.e. having self as the first argument. It is not required if the command is implemented as a function (unbound) or an inner function (already bound).

Parameters
  • commandline

    Either a string with a command and arguments (e.g. "command --flag arg"),

    or a list of string elements (e.g. from sys.argv),

    or any Iterator supplying a list of tokens.

  • base – an object that is passed to the command function as the self argument. Required if any command method has self, not required otherwise.

  • error_handler

    callback function to handle errors when parsing the command line. The handler takes a single argument with a ArgumentError exception. The default is a function that just prints the error to stderr.

    If set to None parsing errors will result in an exception.

  • stdout

    Set to redirect the output of ArgumentParser (e.g. help texts) and the called command function to a different output, e.g. an ssh stream.

    Optional, default is sys.stdout

  • stderr

    Set to redirect error messages from the ArgumentParser and the called command function to a different output, e.g. an ssh stream.

    Optional, default is sys.stderr

  • stdin

    Set to redirect the input of the called command function to an input other than the current terminal, e.g. an ssh stream.

    Optional, default is sys.stdin

Returns

anything the command function/method returns.

Raises
  • ValueError – if the command function requires a self parameter, but no base argument was supplied.

  • ArgumentError – if the given command line contains errors and the error_handler is set to None.

help(command: ZeroOrMore[str]) None

Prints help for the given command.

Parameters

command (list) – Name of the command to get help for

property rootnode: ParserNode

The root node of the ParserNode tree of commands. While the tree can be modified care must be taken to regenerate it after modifications by calling generate_parser() before calling execute().

This property is read only.

Returns

The root node of the ParserNode tree.

class Choices(*args, **kwargs)

Bases: Generic[T]

Tells the ArgumentParser that this argument can only accept some specific values.

These values must be specified in square brackets. This can be either a list of items or anything else that returns a container of values.

In following example the command takes two arguments: the first may be either “foo” or “bar” while the second argument accepts any integer between 1 and 4.

@cli.command
def command(arg1: Choices["foo", "bar"], arg2: Choices[range(1,5)] | int):
    ...

Note

Without from __future__ import annotations Python versions prior to 3.10 do not like strings in type annotations. In this case the choices can be wrapped in a Literal to tell Python (or any type checker) to not evaluate them a load time.

def command(arg1: Choices[Literal["foo", "bar"]], arg2: Choices[Literal[range(1,5)]])

Internally the bracket content from Choices is parsed via eval(), so nothing dangerous should be put there - especially no functions of unknown source. The result from this is then added as choices=... to the argument.

See argparse: choices for more details.

class CountAction(*args, **kwargs)

Bases: int

Tells the ArgumentParser to just count the number of occurences of this argument on the command line.

This action always returns an int and can not be set to any type.

@cli.command
def cmd(v: CountAction)
    return v

parser.execute("cmd -vvvv")   # returns 4

Internally this will add the action="count" option to the argument.

See argparse: action for details.

class CustomAction(*args, **kwargs)

Bases: Generic[T]

Tells the ArgumentParser to use a custom Action to process the command line value for this argument.

CustomAction requires the name of a callable in square brackets. This callable can be either a subclass of argparse.Action or a function with the same signature as the Action class.

class MyAction(argparse.Action):
    def __init__(self, option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None,
                 required=False, help=None, metavar=None)
        ...

@cli.command
def command(arg: CustomAction[MyAction]):
    ...

Internally this will add the action=MyAction option to the argument.

Refer to argument actions and action classes for more details on how to implement a custom action.

class Exactly1(*args, **kwargs)

Bases: Generic[T]

Tells the decorator that this argument has exactly one entry

Internally this will add the nargs=1 option to the argument.

Exactly1 may specify a Type like int in square brackets to tell the decorator what value is acceptable.

On the Python side this will set the type of the argument to a generic List with an optional type as required (default is str)

@cli.command
def cmd(value: Exactly1[float])
    value.as_integer_ratio()

parser.execute("cmd 1.5")       # OK
parser.execute("cmd 1.5 2.5")   # causes an error

See argparse: -nargs for details.

class Exactly2(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 2 arguments.

class Exactly3(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 3 arguments.

class Exactly4(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 4 arguments.

class Exactly5(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 5 arguments.

class Exactly6(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 6 arguments.

class Exactly7(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 7 arguments.

class Exactly8(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 8 arguments.

class Exactly9(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 9 arguments.

class ExtendAction(*args, **kwargs)

Bases: List[T]

class Flag(*args, **kwargs)

Bases: object

Marks the argument as a Flag.

A Flag starts with a single hyphen -.

If the Flag does not require any arguments (just present or not present) add a = False as its default or add a StoreTrueAction annotation.

def cmd(f: Flag = False):
    return f

result = parser.execute("cmd -f")  # result = True
result = parser.execute("cmd")     # result = False  (the default)

See argparse: name-or-flags for details.

class NonExitingArgumentParser(*args, **kwargs)

Bases: ArgumentParser

Slightly modified version of the default ArgumentParser to make it more suitable for a self-contained command line interpreter.

It overrides the exit() and error() methods and removes the sys.exit calls, instead raising an ArgumentError upon errors.

(Pyhton 3.9+) It also sets the exit_on_error flag to a default of False so that internal argument errors are not caught and routed through error() but passed on to the caller directly.

error(message) NoReturn

Error parsing the command line.

This overrides the default behaviour of ArgumentParser (print usage and exit) to just pass the error message to the caller as an ArgumentParser.ArgumentError

Parameters

message – The error message

Raises

ArgumentError with the error message

exit(status=0, message=None)

Overriden to not call sys.exit(). Instead an ArgumentError is raised if the status is not zero.

class OneOrMore(*args, **kwargs)

Bases: List[T]

Tells the decorator that this argument requires one or more values.

Internally this will add the nargs='?' option to the argument.

OneOrMore may specify a Type like int in square brackets to tell the decorator what values are acceptable.

On the Python side this will set the type of the argument to a generic List with an optional type as required (default is str)

def cmd(values: OneOrMore[int])
    for n in values:
        ...

parser.execute("cmd 1 2 3 4")

See argparse: -nargs for details.

class Option(*args, **kwargs)

Bases: object

Marks the argument as an Option.

An Option starts with a double hyphen --.

If the Option does not require any arguments (just present or not present) add a = False as its default or add a StoreTrueAction annotation.

def cmd(foo: Option = False):
    return foo

result = parser.execute("cmd -foo")  # result = True
result = parser.execute("cmd")       # result = False  (the default)

See argparse: name-or-flags for details.

class StoreAction(*args, **kwargs)

Bases: object

Tells the ArgumentParser to just store the command line value in the annotated variable.

This is the default action for an argument and is therefore usually not required.

Internally this will add the action="store" option to the argument.

See argparse: action for details.

class StoreConstAction(*args, **kwargs)

Bases: object

Tells the ArgumentParser to assign the given default value to the argument whenever it is present on the command line.

This is similar to StoreTrueAction but with a generic constant instead of the fixed True.

@cli.command
def cmd(foo: Option | StoreConstAction = 42)
    return foo

parser.execute("cmd --foo")         # returns 42
parser.execute("cmd")               # returns None
parser.execute("cmd --foo 100")     # causes unrecognized argument error

Note

This is not the same as just assigning a default value.

@cli.command
def cmd(foo: Option = 42):
    return foo

cli.execute("cmd --foo")        # causes missing argument error
cli.execute("cmd")              # returns 42
cli.execute("cmd --foo 100")    # returns 100

Internally this will add the action="store_const" option to the argument and take the given default and set it as the const=... option.

See argparse: action for details.

class StoreFalseAction(*args, **kwargs)

Bases: object

Tells the ArgumentParser to set the argument to False whenever it is present on the command line (and True if it is absent).

This is a special case of StoreConstAction with a constant value of False.

@cli.command
def cmd(foo: Option | StoreFalseAction)
    return foo

parser.execute("cmd --foo")         # returns False
parser.execute("cmd")               # returns True

Note

Instead of using StoreFalseAction any Option or Flag can just be given a default of True. Internally this is converted to a StoreFalseAction.

@cli.command
def cmd(foo: Option = True)
    return foo

parser.execute("cmd --foo")         # returns False
parser.execute("cmd")               # returns True

Internally this will add the action="store_false" option to the argument.

See argparse: action for details.

class StoreTrueAction(*args, **kwargs)

Bases: object

Tells the ArgumentParser to set the argument to True whenever it is present on the command line (and False if it is absent).

This is a special case of StoreConstAction with a constant value of True.

@cli.command
def cmd(foo: Option | StoreTrueAction)
    return foo

parser.execute("cmd --foo")         # returns True
parser.execute("cmd")               # returns False

Note

Instead of using StoreTrueAction any Option or Flag can just be given a default of False. Internally this is converted to a StoreTrueAction.

@cli.command
def cmd(foo: Option = False)
    return foo

parser.execute("cmd --foo")         # returns True
parser.execute("cmd")               # returns False

Internally this will add the action="store_true" option to the argument.

See argparse: action for details.

class ZeroOrMore(*args, **kwargs)

Bases: List[T]

Tells the decorator that this argument can have any number of entries, including zero entries.

Internally this will add the nargs='*' option to the argument.

ZeroOrMore may specify a Type like int in square brackets to tell the decorator what values are acceptable.

On the Python side this will set the type of the argument to a generic List with an optional type as required (default is str)

def cmd(values: ZeroOrMore[float])
    for n in values:
        ...

parser.execute("cmd 1 2 3 4")

See argparse: -nargs for details.

class ZeroOrOne(*args, **kwargs)

Bases: Generic[T]

Tells the decorator that this argument can have either one or zero entries

Internally this will add the nargs='?' option to the argument.

ZeroOrMore may specify a Type like int in square brackets to tell the decorator what values are acceptable.

def cmd(value: ZeroOrOne[float])
    value.as_integer_ratio()

parser.execute("cmd 1.5")

See argparse: -nargs for details.

argparsedecorator.argparse_decorator

This module contains one Class, the ArgParseDecorator.

It is the main Class for the argparseDecorator library and usually the only one needed to use the library.

It contains the command() decorator to mark functions/methods as commands and the execute()/execute_async() methods to execute a command line string.

Internally it generates a ParserNode element for each decorated function or method, defining the command and all associated data, and organises them in a tree of commands and sub-commands. The nodes have a reference to the decorated function which is used later to execute the command.

When execute() is called the ParserNode tree is converted to an argparse.ArgumentParser object, which is then used to analyse the given command line. The result from the argparse.ArgumentParser.parse_args() call is then converted to arguments of the decorated function and finally the function is called with the arguments and its (optional) return value is passed on to the caller of execute().

The only other public method of this Class is the add_argument() decorator, which can be used to pass arguments directly to the underlying ArgumentParser in case some special functionality of the argparse library is needed.

class ArgParseDecorator(helpoption: Optional[str] = 'help', hyph_replace: str = '__', argparser_class: Optional[Type[ArgumentParser]] = None, **kwargs)

Bases: object

Build python argparse.ArgumentParser from decorated functions.

It uses the signature and the annotations of the decorated class to determine all arguments and their types. It also uses the docstring for the command description, the help strings for all arguments and some additional metadata that can not be expressed via annotations.

Parameters
  • helpoption

    Either

    • "help" to automatically create a help command, or

    • "-h" to automatically add a -h/--help argument to each command (argparse library default), or

    • None to disable any automatically generated help.

    Defaults to "help"

  • hyph_replace – string to be replaced by - in command names, defaults to __ (two underscores)

  • argparser_class (argparse.ArgumentParser or subclass thereof.) – Class to be used for ArgumentParser, defaults to NonExitingArgumentParser

  • kwargs – Other arguments to be passed to the ArgumentParser, e.g. description or allow_abbrev

add_argument(*args: str, **kwargs: Any) Callable

Decorator to add an argument to the command.

This is an alternative way to add arguments to a function. While its use is usually not required there might be some situations where the function signature and its annotations are not sufficient to accurately describe an argument. In this case the add_argument() decorator can be used. Any pararmeter to this decorator is passed directly to add_argument() method of the underlying ArgumentParser

The decorated function must have an argument of the same name or use *args and **kwargs arguments to retrieve the value of these arguments.

Example:

@parser.command
@parser.add_argument('dest_file', type=argparse.FileType('r', encoding='latin-1'))
@parser.add_argument('--foo', '-f')
def write(*args, **kwargs):
    dest_file = args[0]
    foo = kwargs['foo']
Parameters
  • args – Optional arguments that are passed directly to the ArgumentParser.add_argument() method.

  • kwargs – Optional keyword arguments that are passed directly to the ArgumentParser.add_argument() method.

Returns

The decorator function

property argumentparser: ArgumentParser

The generated argparse.ArgumentParser object.

This property is read only

command(*args: Union[str, Callable], **kwargs: Any) Callable

Decorator to mark a method as an executable command.

This takes the name of the decorated function and adds it to the internal command list. It also analyses the signature and the docstring of the decorated function to gather information about its arguments.

Parameters
  • args – Optional arguments that are passed directly to the add_subparsers() method of the underlying ArgumentParser.

  • kwargs – Optional keyword arguments that are passed directly to the add_subparsers() method of the underlying ArgumentParser.

Returns

The decorator function

property command_dict: Dict[str, Optional[Dict]]

Get a dictionary with all commands in a form suitable for the Python Prompt Toolkit autocompleter function.

See Nested completion for details.

Returns

dict

execute(commandline: ~typing.Union[str, ~typing.List[str], ~shlex.shlex], base: ~typing.Optional = None, error_handler=<function default_error_handler>, stdout: ~typing.TextIO = None, stderr: ~typing.TextIO = None, stdin: ~typing.TextIO = None) Optional

Parse a command line and execute it.

The command line can be a single string which will be split into command and argument tokens via the shlex.shlex lexer with default settings. If the default settings are not appropriate then this method will also accept a customized shlex object as commandline - or any other Iterator (which shlex is)

Alternatively commandline can also be a list of strings with the command name as the first item followed by subcommands and arguments. This can be used to process the command line arguments when called as a Python script by passing sys.argv as the commandline

Note

The base must be supplied if the method implementing the command is a bound method, i.e. having self as the first argument. It is not required if the command is implemented as a function (unbound) or an inner function (already bound).

Parameters
  • commandline

    Either a string with a command and arguments (e.g. "command --flag arg"),

    or a list of string elements (e.g. from sys.argv),

    or any Iterator supplying a list of tokens.

  • base – an object that is passed to the command function as the self argument. Required if any command method has self, not required otherwise.

  • error_handler

    callback function to handle errors when parsing the command line. The handler takes a single argument with a ArgumentError exception. The default is a function that just prints the error to stderr.

    If set to None parsing errors will result in an exception.

  • stdout

    Set to redirect the output of ArgumentParser (e.g. help texts) and the called command function to a different output, e.g. an ssh stream.

    Optional, default is sys.stdout

  • stderr

    Set to redirect error messages from the ArgumentParser and the called command function to a different output, e.g. an ssh stream.

    Optional, default is sys.stderr

  • stdin

    Set to redirect the input of the called command function to an input other than the current terminal, e.g. an ssh stream.

    Optional, default is sys.stdin

Returns

anything the command function/method returns.

Raises
  • ValueError – if the command function requires a self parameter, but no base argument was supplied.

  • ArgumentError – if the given command line contains errors and the error_handler is set to None.

async execute_async(commandline: ~typing.Union[str, ~typing.Iterator[str], ~typing.List[str]], base: ~typing.Optional = None, error_handler=<function default_error_handler>, stdout: ~typing.TextIO = None, stderr: ~typing.TextIO = None, stdin: ~typing.TextIO = None) Optional

Parse a command line and execute it in as an async coroutine.

The command line can be a single string which will be split into command and argument tokens via the shlex.shlex lexer with default settings. If the default settings are not appropriate then this method will also accept a customized shlex object as commandline - or any other Iterator (which shlex is)

Alternatively commandline can also be a list of strings with the command name as the first item followed by subcommands and arguments. This can be used to process the command line arguments when called as a Python script by passing sys.argv as the commandline

Note

The base must be supplied if the method implementing the command is a bound method, i.e. having self as the first argument. It is not required if the command is implemented as a function (unbound) or an inner function (already bound).

Parameters
  • commandline

    Either a string with a command and arguments (e.g. "command --flag arg"),

    or a list of string elements (e.g. from sys.argv),

    or any Iterator supplying a list of tokens.

  • base – an object that is passed to the command function as the self argument. Required if any command method has self, not required otherwise.

  • error_handler

    callback function to handle errors when parsing the command line. The handler takes a single argument with a ArgumentError exception. The default is a function that just prints the error to stderr.

    If set to None parsing errors will result in an exception.

  • stdout

    Set to redirect the output of ArgumentParser (e.g. help texts) and the called command function to a different output, e.g. an ssh stream.

    Optional, default is sys.stdout

  • stderr

    Set to redirect error messages from the ArgumentParser and the called command function to a different output, e.g. an ssh stream.

    Optional, default is sys.stderr

  • stdin

    Set to redirect the input of the called command function to an input other than the current terminal, e.g. an ssh stream.

    Optional, default is sys.stdin

Returns

anything the command function/method returns.

Raises
  • ValueError – if the command function requires a self parameter, but no base argument was supplied.

  • ArgumentError – if the given command line contains errors and the error_handler is set to None.

property rootnode: ParserNode

The root node of the ParserNode tree of commands. While the tree can be modified care must be taken to regenerate it after modifications by calling generate_parser() before calling execute().

This property is read only.

Returns

The root node of the ParserNode tree.

default_error_handler(exc: ArgumentError)

Default error handler that just prints the error message to stderr.

split_commandline(cmdline: Union[str, List[str], Iterator[str]]) List[str]

argparsedecorator.annotations

The Annotations for the argparseDecorator.

This module contains a number of classes that can be used as type annotations to give the decorator more metadata used to describe the argument.

All annotation classes in this module do not contain any code and should not be instantiated. Some annotation classes are generic types which can encapsulate an optional type, e.g.

def command(files: OneOrMore[str])

while other annotations are strictly used as markers and may not encapsulate other types.

def command(verbose: Option | StoreTrueAction)
class AppendAction(*args, **kwargs)

Bases: List[T]

Tells the ArgumentParser to append the command line value to a list.

With this annotation an argument can be specified multiple times on the command line.

@cli.command
def cmd(foo: Option | AppendAction | int)
    return foo

parser.execute("cmd --foo 1 --foo 2")  # returns [1, 2]

Internally this will add the action = "append" option to the argument.

See argparse: action for details.

class Choices(*args, **kwargs)

Bases: Generic[T]

Tells the ArgumentParser that this argument can only accept some specific values.

These values must be specified in square brackets. This can be either a list of items or anything else that returns a container of values.

In following example the command takes two arguments: the first may be either “foo” or “bar” while the second argument accepts any integer between 1 and 4.

@cli.command
def command(arg1: Choices["foo", "bar"], arg2: Choices[range(1,5)] | int):
    ...

Note

Without from __future__ import annotations Python versions prior to 3.10 do not like strings in type annotations. In this case the choices can be wrapped in a Literal to tell Python (or any type checker) to not evaluate them a load time.

def command(arg1: Choices[Literal["foo", "bar"]], arg2: Choices[Literal[range(1,5)]])

Internally the bracket content from Choices is parsed via eval(), so nothing dangerous should be put there - especially no functions of unknown source. The result from this is then added as choices=... to the argument.

See argparse: choices for more details.

class CountAction(*args, **kwargs)

Bases: int

Tells the ArgumentParser to just count the number of occurences of this argument on the command line.

This action always returns an int and can not be set to any type.

@cli.command
def cmd(v: CountAction)
    return v

parser.execute("cmd -vvvv")   # returns 4

Internally this will add the action="count" option to the argument.

See argparse: action for details.

class CustomAction(*args, **kwargs)

Bases: Generic[T]

Tells the ArgumentParser to use a custom Action to process the command line value for this argument.

CustomAction requires the name of a callable in square brackets. This callable can be either a subclass of argparse.Action or a function with the same signature as the Action class.

class MyAction(argparse.Action):
    def __init__(self, option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None,
                 required=False, help=None, metavar=None)
        ...

@cli.command
def command(arg: CustomAction[MyAction]):
    ...

Internally this will add the action=MyAction option to the argument.

Refer to argument actions and action classes for more details on how to implement a custom action.

class Exactly1(*args, **kwargs)

Bases: Generic[T]

Tells the decorator that this argument has exactly one entry

Internally this will add the nargs=1 option to the argument.

Exactly1 may specify a Type like int in square brackets to tell the decorator what value is acceptable.

On the Python side this will set the type of the argument to a generic List with an optional type as required (default is str)

@cli.command
def cmd(value: Exactly1[float])
    value.as_integer_ratio()

parser.execute("cmd 1.5")       # OK
parser.execute("cmd 1.5 2.5")   # causes an error

See argparse: -nargs for details.

class Exactly2(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 2 arguments.

class Exactly3(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 3 arguments.

class Exactly4(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 4 arguments.

class Exactly5(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 5 arguments.

class Exactly6(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 6 arguments.

class Exactly7(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 7 arguments.

class Exactly8(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 8 arguments.

class Exactly9(*args, **kwargs)

Bases: List[T]

The same as Exactly1, except it expects 9 arguments.

class ExtendAction(*args, **kwargs)

Bases: List[T]

class Flag(*args, **kwargs)

Bases: object

Marks the argument as a Flag.

A Flag starts with a single hyphen -.

If the Flag does not require any arguments (just present or not present) add a = False as its default or add a StoreTrueAction annotation.

def cmd(f: Flag = False):
    return f

result = parser.execute("cmd -f")  # result = True
result = parser.execute("cmd")     # result = False  (the default)

See argparse: name-or-flags for details.

class OneOrMore(*args, **kwargs)

Bases: List[T]

Tells the decorator that this argument requires one or more values.

Internally this will add the nargs='?' option to the argument.

OneOrMore may specify a Type like int in square brackets to tell the decorator what values are acceptable.

On the Python side this will set the type of the argument to a generic List with an optional type as required (default is str)

def cmd(values: OneOrMore[int])
    for n in values:
        ...

parser.execute("cmd 1 2 3 4")

See argparse: -nargs for details.

class Option(*args, **kwargs)

Bases: object

Marks the argument as an Option.

An Option starts with a double hyphen --.

If the Option does not require any arguments (just present or not present) add a = False as its default or add a StoreTrueAction annotation.

def cmd(foo: Option = False):
    return foo

result = parser.execute("cmd -foo")  # result = True
result = parser.execute("cmd")       # result = False  (the default)

See argparse: name-or-flags for details.

class StoreAction(*args, **kwargs)

Bases: object

Tells the ArgumentParser to just store the command line value in the annotated variable.

This is the default action for an argument and is therefore usually not required.

Internally this will add the action="store" option to the argument.

See argparse: action for details.

class StoreConstAction(*args, **kwargs)

Bases: object

Tells the ArgumentParser to assign the given default value to the argument whenever it is present on the command line.

This is similar to StoreTrueAction but with a generic constant instead of the fixed True.

@cli.command
def cmd(foo: Option | StoreConstAction = 42)
    return foo

parser.execute("cmd --foo")         # returns 42
parser.execute("cmd")               # returns None
parser.execute("cmd --foo 100")     # causes unrecognized argument error

Note

This is not the same as just assigning a default value.

@cli.command
def cmd(foo: Option = 42):
    return foo

cli.execute("cmd --foo")        # causes missing argument error
cli.execute("cmd")              # returns 42
cli.execute("cmd --foo 100")    # returns 100

Internally this will add the action="store_const" option to the argument and take the given default and set it as the const=... option.

See argparse: action for details.

class StoreFalseAction(*args, **kwargs)

Bases: object

Tells the ArgumentParser to set the argument to False whenever it is present on the command line (and True if it is absent).

This is a special case of StoreConstAction with a constant value of False.

@cli.command
def cmd(foo: Option | StoreFalseAction)
    return foo

parser.execute("cmd --foo")         # returns False
parser.execute("cmd")               # returns True

Note

Instead of using StoreFalseAction any Option or Flag can just be given a default of True. Internally this is converted to a StoreFalseAction.

@cli.command
def cmd(foo: Option = True)
    return foo

parser.execute("cmd --foo")         # returns False
parser.execute("cmd")               # returns True

Internally this will add the action="store_false" option to the argument.

See argparse: action for details.

class StoreTrueAction(*args, **kwargs)

Bases: object

Tells the ArgumentParser to set the argument to True whenever it is present on the command line (and False if it is absent).

This is a special case of StoreConstAction with a constant value of True.

@cli.command
def cmd(foo: Option | StoreTrueAction)
    return foo

parser.execute("cmd --foo")         # returns True
parser.execute("cmd")               # returns False

Note

Instead of using StoreTrueAction any Option or Flag can just be given a default of False. Internally this is converted to a StoreTrueAction.

@cli.command
def cmd(foo: Option = False)
    return foo

parser.execute("cmd --foo")         # returns True
parser.execute("cmd")               # returns False

Internally this will add the action="store_true" option to the argument.

See argparse: action for details.

class ZeroOrMore(*args, **kwargs)

Bases: List[T]

Tells the decorator that this argument can have any number of entries, including zero entries.

Internally this will add the nargs='*' option to the argument.

ZeroOrMore may specify a Type like int in square brackets to tell the decorator what values are acceptable.

On the Python side this will set the type of the argument to a generic List with an optional type as required (default is str)

def cmd(values: ZeroOrMore[float])
    for n in values:
        ...

parser.execute("cmd 1 2 3 4")

See argparse: -nargs for details.

class ZeroOrOne(*args, **kwargs)

Bases: Generic[T]

Tells the decorator that this argument can have either one or zero entries

Internally this will add the nargs='?' option to the argument.

ZeroOrMore may specify a Type like int in square brackets to tell the decorator what values are acceptable.

def cmd(value: ZeroOrOne[float])
    value.as_integer_ratio()

parser.execute("cmd 1.5")

See argparse: -nargs for details.

argparsedecorator.nonexiting_argumentparser

class NonExitingArgumentParser(*args, **kwargs)

Bases: ArgumentParser

Slightly modified version of the default ArgumentParser to make it more suitable for a self-contained command line interpreter.

It overrides the exit() and error() methods and removes the sys.exit calls, instead raising an ArgumentError upon errors.

(Pyhton 3.9+) It also sets the exit_on_error flag to a default of False so that internal argument errors are not caught and routed through error() but passed on to the caller directly.

error(message) NoReturn

Error parsing the command line.

This overrides the default behaviour of ArgumentParser (print usage and exit) to just pass the error message to the caller as an ArgumentParser.ArgumentError

Parameters

message – The error message

Raises

ArgumentError with the error message

exit(status=0, message=None)

Overriden to not call sys.exit(). Instead an ArgumentError is raised if the status is not zero.

Internal Modules

These modules are not part of the ArgParseDecorator API, but they can be used obtain information about the command tree or to implement other methods of adding Commands to the internal command tree.

argparsedecorator.parsernode

ParserNode is a class to store one command and all of its arguments and keeps a list of child ParserNodes for subsommands.

This class also has all the code to parse a function signature and the docstring associated with that function.

class ParserNode(title: Optional[str], parent: Optional[ParserNode] = None, **kwargs)

Bases: object

Single Node of the parser tree.

A tree of nodes is used to represent the complete command hierarchy. The root node is generated automatically by the ArgParseDecorator.

The children are added by successive calls from the command() decorator method. Once the tree is finished, the actual argparse.ArgumentParser representing all commands and their arguments of this node can be accessed by the argumentparser() property.

Each ParserNode has a root() property to get the root node.

Parameters
add_argument(arg: Argument) None

Add a single Argument to this node.

The Argument must be unique, i.e. each Argument may be added only once.

Parameters

arg – single Argument object.

add_arguments(args: Iterable[Argument]) None
property add_help: bool

True if the help system of ArgumentParser is active (i.e. [-h] flag for all commands).

If False this is inhibited. This is useful if the caller supplies its own help system.

This property is valid for this node and all of its children.

Default is False.

analyse_annotation(annotation: Union[Type, str], arg: Argument) None
analyse_annotation_part(part: str, arg: Argument) None
analyse_docstring(func: Callable) None

Parse the docstring to extract the description (anything before the first metadata) and any metadata.

analyse_signature(func: Callable)
property argparser_class: Type[ArgumentParser]

The class to use for building the parser.

Default is the NonExitingArgumentParser class, a subclass of argparse.ArgumentParser that does not call sys.exit(). It can be changed to subclass of ArgumentParser. Only relevant for the root Node. If changed on any other child node the class will be passed to the root node and, if the parser has already been generated, the whole parser will be regenerated.

property argumentparser: ArgumentParser

Get the ArgumentParser representing this Node.

When read the returned object represents the current state of the Node. In case of any change to this Node or to the Tree this argparse.ArgumentParser is regenerated.

property arguments: Dict[str, Argument]

A dictionary of all arguments set for this node.

Read only property.

property bound_method

Is True when the command function is a bound method, i.e. if it requires a self argument.

This property is read only.

property coroutine

Is True when the command function is a coroutine, i.e. if it starts with async def.

This property is read only.

property function: Callable[[Dict[str, Any]], Any]

The function that implements the command.

When set extract all available information from the function signature and from the function docstring.

property function_globals: Dict[str, Any]

Get the globals from the command function.

Autmatically retrieved when the function() property is set to a function.

This property is read only.

generate_parser(parentparser) None

Build the actual argparse.ArgumentParser object for this Node.

If it is not the root Node then the ArgumentParser from the parent must be supplied to add the parser representing this node. If this Node has children then they will be generated as well. Normally this method should only be called once for the root Node.

Parameters

parentparser (argparse.ArgumentParser or subclass thereof) – The ArgumentParser to add this Parser to.

get_argument(name: str) Optional[Argument]

Get the argument with the given name for this command.

If there is no argument with exactly this name then this method will append one or two - to find a match.

Parameters

name – name of the argument, e.g. --foo

Returns

The Argument object or None if no argument with this name.

get_command_dict() Dict[str, Optional[Dict]]

Get a dictionary with all commands in a form suitable for the Python Prompt Toolkit autocompleter function.

See Nested completion for details.

Returns

dict

get_node(command: Union[str, List[str]]) ParserNode

Get the ParserNode representing the given command.

The command can be either a single name or a list with a command and subcommand names. A new node will be created if no node for a command / subcommand exists. Should be used on the root node to make the command global.

Parameters

command – single command name or list of hierachical names.

has_argument(arg: Argument) bool
has_node(command: Union[str, List[str]]) bool

Check if a Node for the given command exists in the Tree.

Best if used on the rootnode to check the whole tree.

Parameters

command – single command name or list of command names (for subcommands)

Returns

True if node exists

no_command(**_) None
optional_args: List[str]

List of all optional (kwargs) arguments of this node.

parse_alias(line: str) None
parse_choices(line: str) None
parse_metavar(line: str) None
parse_param(line: str) None
positional_args: List[str]

List of all positional (args) arguments of this node.

property root: ParserNode

The root node of the ParserNode hierarchy.

property title: str

The name of the command represented by this node.

check_explicit_type(part: str, arg: Argument)
fullname(o)
get_bracket_content(string: str) str

Find the outermost brackets and return their content. For example foo[bar[baz]] will return bar[baz]

Parameters

string – any string

Returns

bracket content or empty string if there were no brackets or if they were empty.

is_type_key(targettype: Type, part: str) bool
resolve_literals(string: str) str
split_strip(string: str, sep: str = ',') List[str]

Split a string and remove all whitespaces.

split_union(string: str) List[str]

argparsedecorator.argument

class Argument(name: str, eval_globals: Optional[Dict[str, Any]] = None)

Bases: object

property action: Union[str, Action]

The Action to perform for this argument. If this property has been set once it will raise an Exception if set to a different action.

add_alias(alias: str)
property alias: List[str]

Other names. Only valid for Flags / Options (starting with ‘-’ / ‘–‘) This property is read only; new aliases can be added with :meth:’add_alias()’ :return: List of other names for this argument

static argument_from_args(*args: str, **kwargs: Any)
property choices: Sequence
property const: T

Optional const value. If set once any further attempts to change to a different value will raise an exception.

property default: T

Optional default value. If set once any further attempts to change to a different value will raise an exception.

property dest: Optional[str]

Get the dest argument. Usually ‘None’, but if any aliases have been set the dest is automatically set to the Argument name, but without any ‘-’ at the beginning. This is to override the argparse default to use the longest optional name.

get_command_line() Tuple[List[str], Dict[str, Any]]
property help: str
property metavar: Optional[Union[str, Tuple]]

Metavar is a name or a tuple of names for the pararmeters of this Argument. :return:

property name: str

The name of this argument. Unique for the associated command.

property nargs: Union[str, int]

Number of additional parameters for this Argument. Either an integer for a fixed number or one of ‘?’, ‘*’ or ‘+’ for one or zero, zero or more, and one or more parameters. If set once any further attempts to change to a different value will raise an exception.

property optional: bool

‘True’ if this argument is an optional argument, i.e. starts with a hyphen ‘-‘.

property positional: bool

‘True’ if this argument is a positional argument, i.e. does not start with a hyphen ‘-‘.

property required: bool
property type: Callable

The type of the Argument. Can be any callable type. Can be a string with the name of the callable.

Warning

As the conversion is done by calling eval() which is a security issue. Do not set this property to any arbitrary user input.

If set once any further attempts to change to a different type will raise an exception.