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.