Development Support

Contents

Development Support#

The DecreeTree class includes some features intended to aid in the development process, specifically for debugging and testing.

Debugging#

Particularly with a complex command tree, any source of errors may not be obvious. To assist users in understanding the execution flow, the debug_print() method has been provided to optionally print internal debugging data. By default it uses standard print statements that expect str.format-style inputs, and defers stringification and substitution much like logging statements (and print calls could be replaced with logging if desired). Calls to debug_print have been placed in key DecreeTree methods.

While it is arguably better to use a true debugger, debugging code flows via print statements is an extremely common approach, and calls to debug_print can facilitate that. Developers can place additional calls to debug_print in DecreeTree subclass methods as desired to enhance the pre-existing output.

Debug printing can be enabled via the debug_tracing argument to run() as described at Runtime Configuration. For example, if root.run(debug_tracing=True) had been used in a variant of basic_tree.py, the results would be the following:

$ python basic_tree_debug_run.py basic_command -e --upper "foo bar"
Running 'root'
Configuring parser tree for 'root'
Configuring root parser for 'root'
Configuring parser tree for 'root -> basic_command' associated with parent subparsers object
Configuring subcommand parser for 'root -> basic_command'
Adding arguments from 'root' to parser
Adding arguments from 'root -> basic_command' to parser
Configuring parser tree for 'root -> double' associated with parent subparsers object
Configuring subcommand parser for 'root -> double'
Adding arguments from 'root' to parser
Adding arguments from 'root -> double' to parser
Preprocessing options for 'root'
Parsing args in 'root'
Found options 'Namespace(_exec_obj_=basic.BasicCommand(), extra=True, upper=True, value='foo bar')'
Setting options for 'root'
Setting options for 'root -> basic_command'
Processing options for 'root'
Processing options for 'root -> basic_command'
Executing 'root'
Extra output
Executing 'root -> basic_command'
FOO BAR

Adding debug_tracing calls to methods such as Root.execute() would further enhance the output.

Testing#

While having a tidy end-to-end process for command execution is great at runtime, it is often necessary to use test data at various stages of execution for testing. DecreeTree supports this by optionally allowing unprocessed or processed command line arguments to be injected.

The primary location for injection is in run() as described at Runtime Configuration. This is supported by preprocess_options(), which actually invokes parser.parse_args() when necessary. To inject a sequence of unparsed string arguments, use the argv argument in the run() method. To inject parsed arguments, circumventing the parser machinery, pass an argparse.Namespace object to run() via the options argument.