util.commandParser module

Inheritance diagram of RedoCommand, IntermediateCommandWord, TopCommandParser, MutatingCommandGenerator, GenFromCommand, GenFromFunction, CommandContext, NoValue

This module defines the following command hierarchy:

Parsable abstract (requires commandName, defineParse())

CommandContext a class that acts as a container for methods, signatures, and Command classes that define commands that are both callable and argparse (command-line style) parsable.

Created on Nov 1, 2024

Code author: Rob Kremer <robkremer@me.com>


class util.commandParser.AbbrevSubParsersAction(option_strings, prog, parser_class, dest='==SUPPRESS==', required=False, help=None, metavar=None)

Bases: _SubParsersAction

Replacement for argparse._SubParsersAction to allow for abbreviations.

__call__(parser, namespace, values, option_string=None)

If we don’t have an exact match for the command commandName, search for a unique prefix match, and go with that one. Error out if there is not match or the match is not unique.

Parameters:
  • parser

  • namespace

  • values

  • option_string

Returns:

Return type:

class util.commandParser._AbbrevChoices

Bases: dict[str, Any]

A replacement for the choices dictionary. Pretends every value is a valid choice, but displays the real choices. Thus, we must rely on AbbrevSubParsersAction to catch the error of a non existant choice.

class util.commandParser.ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[], formatter_class=<class 'argparse.HelpFormatter'>, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True, allow_abbrev=True, exit_on_error=True, *, suggest_on_error=False, color=True)

Bases: ArgumentParser

Trivial override of argparse.ArgumentParser to prevent it from exiting on error.

error(message)
Parameters:

message

util.commandParser.funNameToCommandName(funName: str) → str

In CommandContext classes, this defines the translation from a “signature” method commandName to it’s corresponding util.command.Command class commandName.

Parameters:

funName (str)

Returns:

Return type:

str

util.commandParser.commandNameToFunName(commandName: str) → str

In CommandContext classes, this defines the translation from a util.command.Command class commandName to it’s corresponding “signature” method commandName .

Parameters:

commandName (str)

Returns:

Return type:

str

class util.commandParser.Parsable(commandName: str, topParser: TopCommandParser, **kwargs)

Bases: ABC

This is NOT a command, but a command definition used by a TopCommandParser to generate Command instances suitable for an UndoList. Thus, MutatingCommandGenerator objects act like a class whereas Command objects act like an object.

__init__(commandName: str, topParser: TopCommandParser, **kwargs)
Parameters:
  • commandName (str) – The commandName of the command.

  • topParser (TopCommandParser) – The top parser in the tree of parsers. Used by commands to access defaults, etc.

  • kwarg – Keyword arguments to be passed along the ArgumentParser constructor for this command.

  • kwargs

commandName

The name of the command. The name can be separated by spaces and will be split into subcommands on the spaces.

topParser: TopCommandParser

The top SubParsable in the hierarchy.

parser: ArgumentParser

The associated argparse.ArgumentParser.

immediateSuper: SubParsable

The immediate super-SubParsable.

_makeParser(**kwargs) → tuple[ArgumentParser, SubParsable]
Parameters:

kwarg – Keyword arguments to be passed along the ArgumentParser constructor for this command.

Returns:

The result of self.topParser.addCommand(self.commandName, self, **kwargs).

Return type:

tuple[ArgumentParser, SubParsable]

Used to instantiates self.parser in the constructor.

Parameters:

kwargs

__str__() → str
Returns:

Name of the command or the path to the command (space separated) if this is a multi-word command.

Return type:

str

_abc_impl = <_abc._abc_data object>
class util.commandParser.SubParsable(commandName: str, topParser: TopCommandParser, immediateSuper: SubParsable, help: str, description: str, **kwargs)

Bases: Parsable

A trivial command used as a subparser for multi word commands like pip’s “pip install …” or “pip uninstall …”. These objects act as internal nodes in the tree of command words.

__init__(commandName: str, topParser: TopCommandParser, immediateSuper: SubParsable, help: str, description: str, **kwargs)
Parameters:
  • commandName (str) – The commandName of the command.

  • topParser (TopCommandParser) – The top parser in the tree of parsers. Used by commands to access defaults, etc.

  • immediateSuper (SubParsable) – Another SubParsable under which this one will insert itself.

  • help (str) – The help string for this particular word in the command tree.

  • description (str) – The description string for this particular word in the command tree.

  • kwarg – Keyword arguments to be passed along the ArgumentParser constructor for this command.

Adds to the super version by creating subparsers (calling ArgParser.add_subparsers()) and setting itself up as in internal command tree node.

Parameters:

kwargs

subparsers: _SubParsersAction
commands: list[Parsable]
_makeShortDescription()

Assuming self.parser contains a help description, make a short, summary description for it. The short description will be displayed in the super- parsers help description listing of subcomands, the long one will be in this parser’s specific help.

_abc_impl = <_abc._abc_data object>
class util.commandParser.CommandGenerator(commandName: str, topParser: TopCommandParser, **kwargs)

Bases: SubParsable

This is the top level class for all actual commands that have a ArgParse definition (and thus can be called from a command line).

__init__(commandName: str, topParser: TopCommandParser, **kwargs)
Parameters:
  • topParser (TopCommandParser) – A TopCommandParser object that this object will add itself using topParser.addCommand(self)

  • kwarg – Keyword arguments to be passed along the ArgumentParser constructor for this command.

  • commandName (str)

  • kwargs

_makeParser(**kwargs) → tuple[ArgumentParser, SubParsable]
Parameters:

kwarg – Keyword arguments to be passed along the ArgumentParser constructor for this command.

Returns:

The result of self.topParser.addCommand(self.commandName, self, **kwargs).

Return type:

tuple[ArgumentParser, SubParsable]

Used to instantiates self.parser in the constructor.

Parameters:

kwargs

abstractmethod defineParse()

The actual argparse definition of the command consisting of self.parser.add_argument() calls, etc.

abstractmethod do(args: Namespace) → Any

Execute this command using args.

Parameters:

args (Namespace)

Returns:

Return type:

Any

_abc_impl = <_abc._abc_data object>
class util.commandParser.NonMutatingCommandGenerator(commandName: str, topParser: TopCommandParser, **kwargs)

Bases: CommandGenerator

This is the top level class for all actual commands that do not modify the program’s data (such as informational commands), and thus are not entered into the undo list. As a result they may have a simple implementation without the need of a util.command.Command subclass. Instead, you may simply override the _execute() method with the command’s implementation.

__init__(commandName: str, topParser: TopCommandParser, **kwargs)

See CommandGenerator for parameter doc.

This is technically not a generator, but a simple implmenetion of a command that DOES NOT CHANGE the state of the data, such as a query. It will not be entered on the undo list. There is no associated util.commmand.Command object associated with it.

Parameters:
do(args: Namespace) → Any

Execute this command using args.

Parameters:

args (Namespace)

Returns:

Return type:

Any

abstractmethod _execute(args: Namespace) → Any

Subclasses should override this method to provide the implementation of the command.

Parameters:

args (Namespace)

Returns:

Return type:

Any

_abc_impl = <_abc._abc_data object>
class util.commandParser.GenFromFunction(fun: Callable, commandParser: TopCommandParser, containingClassObject: Any | None = None, commandName: str | None = None, **kwargs)

Bases: NonMutatingCommandGenerator

A command generator for a context’s method that has no Command class: calling it just runs the method (it isn’t undoable).

__init__(fun: Callable, commandParser: TopCommandParser, containingClassObject: Any | None = None, commandName: str | None = None, **kwargs)
Parameters:
  • fun (Callable)

  • commandParser (TopCommandParser)

  • containingClassObject (Optional[Any])

  • commandName (Optional[str])

  • kwargs

fun: Callable
containingClassObject: Any
defineParse()

Build up the existing self.parser from the params and doc of the defining self.fun function.

_execute(args: Namespace) → Any
Parameters:

args (Namespace)

Returns:

Return type:

Any

_abc_impl = <_abc._abc_data object>
class util.commandParser.MutatingCommandGenerator(commandName, commandParser: TopCommandParser, **kwargs)

Bases: CommandGenerator

And abstract class used by TopCommandParser requiring the _makeCommand() method to create a Command object suitable for undo lists.

__init__(commandName, commandParser: TopCommandParser, **kwargs)

See CommandGenerator for parameter doc.

This is NOT a command, but a command definition used by a TopCommandParser to generate Command instances suitable for an UndoList. Thus, MutatingCommandGenerator objects act like a class whereas Command objects act like an object.

Parameters:
do(args: Namespace) → Any
Parameters:

args (Namespace) – A namespace as generated by ArgParse.

Builds the util.command.Command object (by calling the _makeCommand() method), enters it into the undo list, and executes it. This method method is usually called by the the command parser.

Returns:

Return type:

Any

abstractmethod _makeCommand(args: Namespace) → Command
Parameters:

args (Namespace)

Returns:

Return type:

Command

_abc_impl = <_abc._abc_data object>
class util.commandParser.GenFromCommand(commandClass: type[Command], commandParser: TopCommandParser, commandName: str | None = None, **kwargs)

Bases: MutatingCommandGenerator

A command generator for a context’s method that has a Command class (eg: move() and _Move): running it makes the Command and does it on the undo list.

__init__(commandClass: type[Command], commandParser: TopCommandParser, commandName: str | None = None, **kwargs)
Parameters:
commandClass: type[Command]
_makeCommand(args: Namespace) → Command
Parameters:

args (Namespace)

Returns:

Return type:

Command

defineParse()

Build up the existing self.parser from the __init__ params and doc of the defining Command class given in self.commandClass.

_abc_impl = <_abc._abc_data object>
class util.commandParser.RedoCommand(topParser: TopCommandParser)

Bases: NonMutatingCommandGenerator

The redo command (see UndoCommand).

__init__(topParser: TopCommandParser)
Parameters:

topParser (TopCommandParser)

_execute(args: Namespace) → list[str] | str | Any
Parameters:

args (Namespace)

Returns:

Return type:

list[str] | str | Any

defineParse()

The actual argparse definition of the command consisting of self.parser.add_argument() calls, etc.

_abc_impl = <_abc._abc_data object>
class util.commandParser.NoValue

Bases: object

Used to represent no value for an object when None is otherwise a possible value.

class util.commandParser.IntermediateCommandWord(commandName: str, commandParser: TopCommandParser, immediateSuper: SubParsable, help: str | None = None, description: str | None = None, **kwargs)

Bases: SubParsable

Used for multi-word commands like “model node update”. Obviously, these must have subcommands, so the subparsers list self.subparsers is instantiated in the constructor.

__init__(commandName: str, commandParser: TopCommandParser, immediateSuper: SubParsable, help: str | None = None, description: str | None = None, **kwargs)
Parameters:
  • commandName (str)

  • commandParser (TopCommandParser)

  • immediateSuper (SubParsable)

  • help (Optional[str])

  • description (Optional[str])

  • kwargs

_abc_impl = <_abc._abc_data object>
class util.commandParser.TopCommandParser(commandName: str, doList: ~util.command.DoList | None = None, loadCommandsFrom: list[~util.commandParser.CommandContext] = [], ignore: ~typing.Callable[[str], bool] = <function TopCommandParser.<lambda>>, defaults: dict[str, ~typing.Any] | None = None, decoders: dict[str, ~typing.Callable[[str], ~typing.Any]] | None = None, description: str = '', **args)

Bases: SubParsable

A Command container meant to be the central hub for interpreting and executing command language commands through iterative calls to parse() or parseLine().

__init__(commandName: str, doList: ~util.command.DoList | None = None, loadCommandsFrom: list[~util.commandParser.CommandContext] = [], ignore: ~typing.Callable[[str], bool] = <function TopCommandParser.<lambda>>, defaults: dict[str, ~typing.Any] | None = None, decoders: dict[str, ~typing.Callable[[str], ~typing.Any]] | None = None, description: str = '', **args)
Parameters:
  • commandName (str) – The commandName of the command.

  • description (str) – What help (with no arguments) says before the list of commands: eg: the syntax of the language’s arguments.

  • doList (DoList) – An undo list to use. By default, a new one will be created.

  • kwarg – Keyword arguments to be passed along the ArgumentParser constructor.

Adds to the super version by setting itself as an empty root command, insuring there is a dolist, and instantiating undo, redo, help, and debug commands. The debug command merely sets or clear a self.debug boolean for other commands to use as appropriate.

Parameters:
  • loadCommandsFrom (list[CommandContext])

  • ignore (Callable[[str], bool])

  • defaults (Optional[dict[str, Any]])

  • decoders (Optional[DecodersType])

  • args

description: str

What help says before the list of commands.

doList: DoList

All mutating commands will be added to the the dolist.

defaults: dict[str, Any]

Defaults are automatically filled in whenever a parameter name matches a default name and has a NoValue value. Name->Any.

decoders: dict[str, Callable[[str], Any]]

Used to translate str parameters to actual objects. Type->function.

debug: bool

Debug flag

args: Namespace | None

The last argparse arguments used.

currentContextClass: Type[CommandContext] | None
addCommand(commandName: str, command: Parsable, context: CommandContext | None = None, **kwargs) → tuple[ArgumentParser, SubParsable]
Parameters:
  • commandName (str) – The commandName if the command. May be a simple commandName like “delete”, in which case the command will be added to this node in the command tree; or it may be a multi-word command path like “modify node commandName”, in which case the any intermediate nodes in the command tree will be created (if they don’t already exist) and the command will be added at the last commandName in the the path.

  • command (Parsable) – A Parsable object to add to the command tree in the position as described above.

  • kwargs – keyword arguments to be passed to the new command’s parser’s constructor (an ArgumentParser)

Returns:

the ArgumentParser created and this SubParsable’s immediate parent in the command tree (another SubParsable).

Return type:

tuple[ArgumentParser, SubParsable]

Add a command to this container and create and return a sub parser for that command. The idea being that commands that change state are Command commands and interact with the DoList while commands that are strictly informational are MutatingCommandGenerator (:> Command ) don’t interact with the DoList .

Note

The commandName parameter may contain spaces indicating a chain of commands, thus you might have command names “modify node” which will create a subparser “modify” with command “node” to execute the command’s code. If later you add command “modify relation”, the “relation” command will be added to “modify“‘s list of commands. Thus you have commands:

> modify node …

> modify relation …

> modify <<Raises a SyntaxError>>

Parameters:

context (Optional[CommandContext])

_makeParser(**kwargs) → tuple[ArgumentParser, SubParsable]
Parameters:

kwargs

Returns:

Return type:

tuple[ArgumentParser, SubParsable]

static _strToComList(line: str) → list[str]
Parameters:

line (str)

Returns:

Return type:

list[str]

static _comListToStr(com: list[str]) → str
Parameters:

com (list[str])

Returns:

Return type:

str

parseLine(line: str) → Any
Parameters:

line (str) – A command line to interpret and execute.

Returns:

The result of executing the command.

Return type:

Any

Interpret the line string by spliting it respecting quotes, then call parse().

lastArgs()

Return the set of args parsed from the last parse.

Returns:

Return type:

parse(argsList: list[str]) → Any
  • Parse the command line using parser

  • if it creates a command, execute it either on the doList if we have one or otherwise

  • return the result of the execution

Parameters:

argsList (list[str])

Returns:

Return type:

Any

loadCommands(context: ~util.commandParser.CommandContext, ignore: ~typing.Callable[[str], bool] = <function TopCommandParser.<lambda>>)
Parameters:
_abc_impl = <_abc._abc_data object>
class util.commandParser.CommandContext(parser: TopCommandParser | None = None)

Bases: object

A container of commands: each public method is a command, callable from code and parsable from a command line (its name’s words, eg: new_node is “new node”; its parameters, the arguments and options). A method with a matching nested Command class (move() and _Move) is done through the undo list, so it can be undone. Arguments are converted by the context’s decoders, and missing ones filled in from its defaults.

commandSynonyms: dict[str, Iterable[str]] = {}

The methodname -> list[synonym] defining synonyms for commands

optionSynonyms: dict[str, dict[str, list[str]]] = {'redo': {'next': ['-n'], 'queue': ['-q']}, 'undo': {'next': ['-n'], 'queue': ['-q']}}

The methodname -> (option -> list[synonym]) dict for command definitions in this context.

commandHelp: dict[str, str] = {}

The command-name -> help-string dict for intermediate commands in this context.

__init__(parser: TopCommandParser | None = None)
Parameters:

parser (Optional[TopCommandParser])

parser: TopCommandParser

The associatated parser.

doList: DoList

The DoList for all mutating commands.

defaults: dict[str, Any]

The defaults (name->value) dict for command definitions in this context.

decoders: dict[str, Callable[[str], Any]]
_capture: CompositeCommandMgr | None

Used to capture commands to combine in a CompositeCommand.

_defineDecoders()
_setCapture(capture: CompositeCommandMgr | None)
Parameters:

capture (CompositeCommandMgr | None)

help(topic: list[str] | None) → None

Show a list of all commands pr help on a specific topic”

Parameters:

topic (list[str]|None) – The topic print help for.

debug(state: str | None = None, /) → bool

Get or turn on or off the debug state. When debug is on, tracebacks are printed for errors; when it’s off, simple exception messages are printed. If no argument is present, the current debug state is printed.

Parameters:

state (str|None) – can be missing, “on”, “off”, “true”, or “false”, or unique abbreviations of those.

Returns:

The new (or current) debug state.

Return type:

bool

undo(queue: bool = False, next: bool = False)

Undo the last command executed.

Parameters:
  • queue (bool) – Return a list of strings describing the actions in the undo queue.

  • next (bool) – Return a string describing the action next in the undo queue.

Returns:

If neither of the options is present, returns whatever the result of undoing the last action.

Return type:

Any

redo(queue: bool = False, next: bool = False)

Redo the last command that was undone by the undo command.

Parameters:
  • queue (bool) – Return a list of strings describing the actions in the redo queue.

  • next (bool) – Return a string describing the action next in the redo queue.

Returns:

If neither of the options is present, returns whatever the result of redoing the action.

Return type:

Any

default(defName: str, value: Any = <class 'util.commandParser.NoValue'>, /, _defaults: dict[str, ~typing.Any] | None=None) → Any

Set or get a parser-global command default. If value is omitted the current default is simply returned.

Parameters:
  • commandName (str) – The commandName of the param to have the default filled in.

  • value (Any|None) – The default value.

  • defName (str)

  • _defaults (Optional[dict[str, Any]])

Returns:

Return type:

Any

class _Default(defName: str, value: Any = <class 'util.commandParser.NoValue'>, /, _commandContext: CommandContext | None = None)

Bases: Command

The command that sets one of a context’s defaults (see CommandContext.default()).

__init__(defName: str, value: Any = <class 'util.commandParser.NoValue'>, /, _commandContext: CommandContext | None = None)

Set or get a parser-global command default. If value is omitted the current default is simply returned.

Parameters:
  • commandName (str) – The commandName of the param to have the default filled in.

  • value (Any|None) – The default value.

  • defName (str)

  • _commandContext (Optional[CommandContext])

_abc_impl = <_abc._abc_data object>
do()
Returns:

Return type:

undo()
Returns:

Return type:

delete()

Override to destroy any data when the the command becomes unreachable. Called from DoList when new commands override the tail of the do-queue.

__str__() → str
Returns:

Return type:

str

class util.commandParser.CompositeCommand(commands: list[Command])

Bases: Command

Several commands as one: done in order, and undone in reverse order.

_abc_impl = <_abc._abc_data object>
__init__(commands: list[Command])
Parameters:

commands (list[Command])

commands: list[Command]
do() → Any
Returns:

Return type:

Any

undo() → Any
Returns:

Return type:

Any

delete()

Override to destroy any data when the the command becomes unreachable. Called from DoList when new commands override the tail of the do-queue.

class util.commandParser.CompositeCommandMgr(context: CommandContext)

Bases: object

A context manager that groups the commands called on a CommandContext inside its with block into one CompositeCommand – one entry on the undo list. The commands are queued, not run, until the block ends.

__init__(context: CommandContext)
Parameters:

context (CommandContext)

commands: list[Command]
context: CommandContext
_addCommand(command: Command)
Parameters:

command (Command)

util.commandParser.fixKwargs(fun: Callable, args: list[Any], kwargs: dict[str, Any], defaults: dict[str, Any], decoders: dict[str, Callable[[str], Any]]) → tuple[list[Any], dict[str, Any]]

Given a function and a kwargs dict where the kwargs may be from a argParse Namespace (containing extra elements), return a kwargs dict that’s legal for the given function. But also:

  • fill in any defaults for param names that match defaults keys have None values.

  • decode any str param values for types in the fun signature that have str values in kwargs.

  • decode each element of a list-of-str param value (eg: from an argparse nargs) with the decoder for the element type of a list[...] in the annotation (or failing that, for the annotation itself) – unless that allows str (eg: list[str|GraphObject]: the function looks them up).

  • decoders that don’t take **kwargs run first; those that do are then called with the (already decoded) other params as kwargs.

  • a value that won’t decode stays a str if the annotation (or the list’s element type) allows str; otherwise a ValueError naming the param (as --name if it’s an option) is raised, chained from the decoder’s exception.

Parameters:
  • fun (Callable)

  • args (list[Any])

  • kwargs (dict[str, Any])

  • defaults (dict[str, Any])

  • decoders (DecodersType)

Returns:

Return type:

tuple[list[Any], dict[str, Any]]