command

class runcommands.command.Command(implementation=None, name=None, description=None, base_command=None, timed=False, data=None, read_config=False, creates=None, sources=None, callbacks=None, arg_config=None, default_args=None, debug=False)[source]

Wraps a callable and provides a command line argument parser.

Parameters:
  • implementation (callable) – A callable that implements the command’s functionality. The command’s console script will be generated by inspecting this callable.
  • name (str) – Name of command as it will be called from the command line. Defaults to implementation.__name__ (with underscores replaced with dashes).
  • description (str) – Description of command shown in command help. Defaults to implementation.__doc__.
  • timed (bool) – Whether the command should be timed. Will print an info message showing how long the command took to complete when True. Defaults to False.
  • data (Mapping) – Arbitrary data to attach to the command.
  • read_config (bool) – Read args from config file (pyproject.toml or setup.cfg). This is intended for use with standalone console scripts as a way for the end user to specify default args without having to know anything about RunCommands. Defaults to False.
  • sources (str|str[]) – Source path or paths that the command uses to create output paths. If this is specified, then creates must be specified too.
  • creates (str|str[]) – Output path or paths that the command creates. This can be specified without sources; in this case, the output path(s) will be created only when they don’t already exist.
  • callbacks (list) – A list of callables that will be called after the command completes. When multiple commands are run at once, their callbacks will be run in the opposite order in which the corresponding commands are run–i.e., the callbacks for the last command will be run first.
  • arg_config (dict) – For commands defined as classes, this can be used to configure common base args instead of repeating the configuration for each subclass. Note that its keys should be actual parameter names and not normalized arg names.
  • debug (bool) – When this is set, additional debugging info will be shown.
Other attributes:
module: Module containing command
For a class, this is just self.__class__.__module__ For a function, this is self.implementation.__module__
qualname: Qualified name of command within module
For a class, this is just self.__class__.__qualname For a function, this is self.implementation.__qualname__

This is typically used via the command() decorator:

from runcommands import command

@command
def my_command():
    ...

Decorating a function with command() will create an instance of Command with the wrapped function as its implementation.

Args can be passed to command(), which will be passed through to the Command constructor:

@command(name='better-name')
def my_command():
    ...

It’s also possible to use a class directly as a command:

@command
class MyCommand(Command):

    def implementation(self):
        ...

Using the command() decorator on a class will create an instance of the class in the namespace where the class is defined.

Command Names:

A command’s name is derived from the normalized name of its implementation function by default:

@command
def some_command():
    ...

# Command name: some-command

A name can be set explicitly instead, in which case it won’t be normalized:

@command(name='do_stuff')
def some_command():
    ...

# Command name: do_stuff

If the command is defined as a class, its name will be derived from its class name by default (split into words then normalized):

class SomeCommand(Command):
    ...

# Command name: some-command

The command decorator or a class-level attribute can be used to set the command’s name explicitly:

@command(name='do_stuff')
class SomeCommand(Command):
    ...

class SomeCommand(Command):
    name = 'do_stuff'

# Command name in both cases: do_stuff
args[source]

Create args from function parameters.

config_file_args[source]

Get default args from config file.

This looks in pyproject.toml and setup.cfg for default args for this command. The sections that will be searched are:

  • runcommands.{self.name}.args
  • {self.name}.args

Any args that are found will be converted using the arg’s type converter. Boolean args should use “1”, “true”, “0”, or “false”.

Note

TOML converts unquoted values, which may not be desirable. To avoid this, quote values in pyproject.toml.

Note

This is intended for use with standalone console scripts to provide an easy way for the end user to specify default args without needing to know anything about RunCommands. When creating a collection of commands to be run via run, default args can be specified in commands.toml instead.

Note

The first time a config file is loaded, its contents are cached to reduce file reads.

console_script(argv=None, **overrides)[source]

Run the command and then sys.exit().

When exiting isn’t desired (e.g. in tests), wrap the call to this method in a try/except black that catches SystemExit.

environ_args[source]

Get default args from environment variables.

These take precedence over defaults read from a config file for both collections and standalone console scripts.

Any args that are found will be converted using the arg’s type converter. Boolean args should use “1”, “true”, “0”, or “false”.

Note

This is probably more useful with standalone console scripts versus collections of commands. The latter tend to have more complex configuration that might be better defined in a config file.

expand_short_options(argv)[source]

Convert grouped short options like -abc to -a, -b, -c.

This is necessary because we set allow_abbrev=False on the ArgumentParser in self.arg_parser. The argparse docs say allow_abbrev applies only to long options, but it also affects whether short options grouped behind a single dash will be parsed into multiple short options.

See parse_multi_short_option() for details on how multi short options are parsed.

Returns:Original argv if no multi short options found list: Expanded argv if multi short options found
Return type:list
find_arg(name)[source]

Find arg by normalized arg name or parameter name.

find_parameter(name)[source]

Find parameter by name or normalized arg name.

option_map[source]

Map command-line options to args.

parse_multi_short_option(arg)[source]

Parse args like ‘-xyz’ into [‘-x’, ‘-y’, ‘-z’].

Examples:

'abc' -> None, None                   # not an option
'--option' -> None, None              # long option
'-a' -> None, None                    # short option but not multi
'-xyz' -> ['-x', '-y', '-z'], None    # multi short option
'-xyz12' -> ['-x', '-y', '-z'], '12'  # multi short option w/ value

Note that parsing stops when a short option that takes a value is encountered–the rest of the arg string is considered the value for that option.

Returns:The arg is not a multi short option (list, str|None): The arg is a multi short option (perhaps
including a value for the last option)
Return type:(None, None)
parse_optional(string)[source]

Parse string into name, option, and value (if possible).

If the string is a known option name, the string, the corresponding option, and None will be returned.

If the string has the form --option=<value> or -o=<value>, it will be split on equals into an option name and value. If the option name is known, the option name, the corresponding option, and the value will be returned.

In all other cases, None will be returned to indicate that the string doesn’t correspond to a known option.

process_result(result, argv, stdout=None, stderr=None)[source]

Process the result returned by a command.

should_create()[source]

Determine whether output paths should be created.

Returns True when any* output path doesn’t already exist or when any source path was modified more recently than any output path.

Returns False in all other cases.

Note

This should only be called when self.creates is specified.

Note

When a command creates paths but no source paths are specified, the output paths will be created when at least one output path doesn’t already exist.

subcommand(name=None, description=None, timed=False, data=None, read_config=None, creates=None, sources=None, callbacks=None, cls=None)[source]

Create a subcommand of the specified base command.

class runcommands.command.Command(implementation=None, name=None, description=None, base_command=None, timed=False, data=None, read_config=False, creates=None, sources=None, callbacks=None, arg_config=None, default_args=None, debug=False)[source]

Wraps a callable and provides a command line argument parser.

Parameters:
  • implementation (callable) – A callable that implements the command’s functionality. The command’s console script will be generated by inspecting this callable.
  • name (str) – Name of command as it will be called from the command line. Defaults to implementation.__name__ (with underscores replaced with dashes).
  • description (str) – Description of command shown in command help. Defaults to implementation.__doc__.
  • timed (bool) – Whether the command should be timed. Will print an info message showing how long the command took to complete when True. Defaults to False.
  • data (Mapping) – Arbitrary data to attach to the command.
  • read_config (bool) – Read args from config file (pyproject.toml or setup.cfg). This is intended for use with standalone console scripts as a way for the end user to specify default args without having to know anything about RunCommands. Defaults to False.
  • sources (str|str[]) – Source path or paths that the command uses to create output paths. If this is specified, then creates must be specified too.
  • creates (str|str[]) – Output path or paths that the command creates. This can be specified without sources; in this case, the output path(s) will be created only when they don’t already exist.
  • callbacks (list) – A list of callables that will be called after the command completes. When multiple commands are run at once, their callbacks will be run in the opposite order in which the corresponding commands are run–i.e., the callbacks for the last command will be run first.
  • arg_config (dict) – For commands defined as classes, this can be used to configure common base args instead of repeating the configuration for each subclass. Note that its keys should be actual parameter names and not normalized arg names.
  • debug (bool) – When this is set, additional debugging info will be shown.
Other attributes:
module: Module containing command
For a class, this is just self.__class__.__module__ For a function, this is self.implementation.__module__
qualname: Qualified name of command within module
For a class, this is just self.__class__.__qualname For a function, this is self.implementation.__qualname__

This is typically used via the command() decorator:

from runcommands import command

@command
def my_command():
    ...

Decorating a function with command() will create an instance of Command with the wrapped function as its implementation.

Args can be passed to command(), which will be passed through to the Command constructor:

@command(name='better-name')
def my_command():
    ...

It’s also possible to use a class directly as a command:

@command
class MyCommand(Command):

    def implementation(self):
        ...

Using the command() decorator on a class will create an instance of the class in the namespace where the class is defined.

Command Names:

A command’s name is derived from the normalized name of its implementation function by default:

@command
def some_command():
    ...

# Command name: some-command

A name can be set explicitly instead, in which case it won’t be normalized:

@command(name='do_stuff')
def some_command():
    ...

# Command name: do_stuff

If the command is defined as a class, its name will be derived from its class name by default (split into words then normalized):

class SomeCommand(Command):
    ...

# Command name: some-command

The command decorator or a class-level attribute can be used to set the command’s name explicitly:

@command(name='do_stuff')
class SomeCommand(Command):
    ...

class SomeCommand(Command):
    name = 'do_stuff'

# Command name in both cases: do_stuff
args[source]

Create args from function parameters.

config_file_args[source]

Get default args from config file.

This looks in pyproject.toml and setup.cfg for default args for this command. The sections that will be searched are:

  • runcommands.{self.name}.args
  • {self.name}.args

Any args that are found will be converted using the arg’s type converter. Boolean args should use “1”, “true”, “0”, or “false”.

Note

TOML converts unquoted values, which may not be desirable. To avoid this, quote values in pyproject.toml.

Note

This is intended for use with standalone console scripts to provide an easy way for the end user to specify default args without needing to know anything about RunCommands. When creating a collection of commands to be run via run, default args can be specified in commands.toml instead.

Note

The first time a config file is loaded, its contents are cached to reduce file reads.

console_script(argv=None, **overrides)[source]

Run the command and then sys.exit().

When exiting isn’t desired (e.g. in tests), wrap the call to this method in a try/except black that catches SystemExit.

environ_args[source]

Get default args from environment variables.

These take precedence over defaults read from a config file for both collections and standalone console scripts.

Any args that are found will be converted using the arg’s type converter. Boolean args should use “1”, “true”, “0”, or “false”.

Note

This is probably more useful with standalone console scripts versus collections of commands. The latter tend to have more complex configuration that might be better defined in a config file.

expand_short_options(argv)[source]

Convert grouped short options like -abc to -a, -b, -c.

This is necessary because we set allow_abbrev=False on the ArgumentParser in self.arg_parser. The argparse docs say allow_abbrev applies only to long options, but it also affects whether short options grouped behind a single dash will be parsed into multiple short options.

See parse_multi_short_option() for details on how multi short options are parsed.

Returns:Original argv if no multi short options found list: Expanded argv if multi short options found
Return type:list
find_arg(name)[source]

Find arg by normalized arg name or parameter name.

find_parameter(name)[source]

Find parameter by name or normalized arg name.

option_map[source]

Map command-line options to args.

parse_multi_short_option(arg)[source]

Parse args like ‘-xyz’ into [‘-x’, ‘-y’, ‘-z’].

Examples:

'abc' -> None, None                   # not an option
'--option' -> None, None              # long option
'-a' -> None, None                    # short option but not multi
'-xyz' -> ['-x', '-y', '-z'], None    # multi short option
'-xyz12' -> ['-x', '-y', '-z'], '12'  # multi short option w/ value

Note that parsing stops when a short option that takes a value is encountered–the rest of the arg string is considered the value for that option.

Returns:The arg is not a multi short option (list, str|None): The arg is a multi short option (perhaps
including a value for the last option)
Return type:(None, None)
parse_optional(string)[source]

Parse string into name, option, and value (if possible).

If the string is a known option name, the string, the corresponding option, and None will be returned.

If the string has the form --option=<value> or -o=<value>, it will be split on equals into an option name and value. If the option name is known, the option name, the corresponding option, and the value will be returned.

In all other cases, None will be returned to indicate that the string doesn’t correspond to a known option.

process_result(result, argv, stdout=None, stderr=None)[source]

Process the result returned by a command.

should_create()[source]

Determine whether output paths should be created.

Returns True when any* output path doesn’t already exist or when any source path was modified more recently than any output path.

Returns False in all other cases.

Note

This should only be called when self.creates is specified.

Note

When a command creates paths but no source paths are specified, the output paths will be created when at least one output path doesn’t already exist.

subcommand(name=None, description=None, timed=False, data=None, read_config=None, creates=None, sources=None, callbacks=None, cls=None)[source]

Create a subcommand of the specified base command.