cement.ext.ext_argparse
¶
The Argparse Extension provides argument handling based on
argparse.ArgumentParser
, and is the default argument handler
used by cement.core.foundation.CementApp
. In addition, this
extension also provides ArgparseController
that enables rapid
development via application controllers based on Argparse.
Requirements¶
- Python 2.7+, Python 3+
- Some features of
ArgparseController
are only available in Python 3 including controller and function/commandaliases
(Python 3+) and controller default functions/command (Python 3.4+).
Configuration¶
This extension does not have any application configuration settings.
Usage¶
The following is an example application using both the
ArgparseArgumentHandler
and ArgparseController
. Note that
the default arg_handler
is already set to
ArgparseArgumentHandler`
by CementApp
.
from cement.core.foundation import CementApp
from cement.ext.ext_argparse import ArgparseController, expose
class BaseController(ArgparseController):
class Meta:
label = 'base'
arguments = [
(['--base-foo'], dict(help='base foo option')),
]
@expose(hide=True)
def default(self):
# Note: Default commands are only available in Python 3.4+
print('Inside BaseController.default')
if self.app.pargs.base_foo:
# do something with self.app.pargs.base_foo
print('Base Foo > %s' % self.app.pargs.base_foo)
@expose(
arguments=[
(['--command1-opt'],
dict(help='option under command1', action='store_true'))
],
aliases=['cmd1'],
help='command1 is a sub-command under myapp base controller',
)
def command1(self):
print('Inside BaseController.command1')
if self.app.pargs.command1_opt:
# do something with self.app.pargs.command1_opt
pass
class EmbeddedController(ArgparseController):
class Meta:
label = 'embedded_controller'
stacked_on = 'base'
stacked_type = 'embedded'
@expose(help="command2 embedded under base controller")
def command2(self):
print('Inside EmbeddedController.command2')
class NestedController(ArgparseController):
class Meta:
label = 'nested_controller'
stacked_on = 'base'
stacked_type = 'nested'
arguments = [
(['--nested-opt'],
dict(help='option under nested-controller')),
]
@expose(help="command3 under nested-controller")
def command3(self):
print('Inside NestedController.command3')
class MyApp(CementApp):
class Meta:
label = 'myapp'
handlers = [
BaseController,
EmbeddedController,
NestedController
]
with MyApp() as app:
app.run()
The above looks like:
$ python myapp.py --help
usage: myapp.py [-h] [--debug] [--quiet] [--base-foo BASE_FOO]
{nested-controller,command1,cmd1,default,command2} ...
optional arguments:
-h, --help show this help message and exit
--debug toggle debug output
--quiet suppress all output
--base-foo BASE_FOO base foo option
sub-commands:
{nested-controller,command1,cmd1,default,command2}
nested-controller nested-controller controller
command1 (cmd1) command1 is a sub-command under base controller
command2 command2 embedded under base controller
$ python myapp.py --base-foo bar
Inside BaseController.default
Base Foo > bar
$ python myapp.py command1 --help
usage: myapp.py command1 [-h] [--command1-opt]
optional arguments:
-h, --help show this help message and exit
--command1-opt option under command1
$ python myapp.py command1
Inside BaseController.command1
$ python myapp.py command2
Inside EmbeddedController.command2
$ python myapp.py nested-controller --help
usage: myapp.py nested-controller [-h] [--nested-opt] {command3} ...
optional arguments:
-h, --help show this help message and exit
--nested-opt option under nested-controller
sub-commands:
{command3}
command3 command3 under nested-controller
$ python myapp.py nested-controller command3
Inside NestedController.command3
-
class
cement.ext.ext_argparse.
ArgparseArgumentHandler
(*args, **kw)¶ Bases:
argparse.ArgumentParser
,cement.core.arg.CementArgumentHandler
This class implements the
cement.core.arg.IArgument
interface, and sub-classes fromargparse.ArgumentParser
. Please reference the argparse documentation for full usage of the class.Arguments and Keyword arguments are passed directly to ArgumentParser on initialization.
-
class
Meta
¶ Bases:
object
Handler meta-data.
-
ignore_unknown_arguments
= False¶ Whether or not to ignore any arguments passed that are not defined. Default behavoir by Argparse is to raise an “unknown argument” exception by Argparse.
This affectively triggers the difference between using
parse_args
andparse_known_args
. Unknown arguments will be accessible asunknown_args
.
-
interface
¶ The interface that this class implements.
alias of
IArgument
-
label
= 'argparse'¶ The string identifier of the handler.
-
-
ArgparseArgumentHandler.
add_argument
(*args, **kw)¶ Add an argument to the parser. Arguments and keyword arguments are passed directly to
ArgumentParser.add_argument()
. See theargparse.ArgumentParser
documentation for help.
-
ArgparseArgumentHandler.
parse
(arg_list)¶ Parse a list of arguments, and return them as an object. Meaning an argument name of ‘foo’ will be stored as parsed_args.foo.
Parameters: arg_list – A list of arguments (generally sys.argv) to be parsed. Returns: object whose members are the arguments parsed.
-
class
-
class
cement.ext.ext_argparse.
ArgparseController
(*args, **kw)¶ Bases:
cement.core.handler.CementBaseHandler
This is an implementation of the
cement.core.controller.IController
interface, but as a base class that application controllers should subclass from. Registering it directly as a handler is useless.NOTE: This handler requires that the applications
arg_handler
beargparse
. If using an alternative argument handler you will need to write your own controller base class or modify this one.NOTE: This is a re-implementation of
cement.core.controller.CementBaseController
. In the future, this class will eventually replace it as the default.Usage:
from cement.ext.ext_argparse import ArgparseController class Base(ArgparseController): class Meta: label = 'base' description = 'description at the top of --help' epilog = "the text at the bottom of --help." arguments = [ (['-f', '--foo'], dict(help='my foo option', dest='foo')), ] class Second(ArgparseController): class Meta: label = 'second' stacked_on = 'base' stacked_type = 'embedded' arguments = [ (['--foo2'], dict(help='my foo2 option', dest='foo2')), ]
-
class
Meta
¶ Bases:
object
Controller meta-data (can be passed as keyword arguments to the parent class).
-
aliases
= []¶ A list of aliases for the controller/sub-parser. Only available in Python > 3.
-
arguments
= []¶ Arguments to pass to the argument_handler. The format is a list of tuples whos items are a ( list, dict ). Meaning:
[ ( ['-f', '--foo'], dict(help='foo option', dest='foo') ), ]
This is equivelant to manually adding each argument to the argument parser as in the following example:
add_argument('-f', '--foo', help='foo option', dest='foo')
-
config_defaults
= {}¶ Configuration defaults (type: dict) that are merged into the applications config object for the config_section mentioned above.
-
config_section
= None¶ A config [section] to merge config_defaults into. Cement will default to controller.<label> if None is set.
-
default_func
= 'default'¶ Function to call if no sub-command is passed. Note that this can not start with an
_
due to backward compatibility restraints in how Cement discovers and maps commands.Note: Currently, default function/sub-command only functions on Python > 3.4. Previous versions of Python/Argparse will throw the exception
error: too few arguments
.
-
description
= None¶ Description for the sub-parser group in help output.
-
epilog
= None¶ The text that is displayed at the bottom when
--help
is passed.
-
help
= None¶ Text for the controller/sub-parser group in help output (for nested stacked controllers only).
-
hide
= False¶ Whether or not to hide the controller entirely.
-
interface
¶ alias of
IController
-
label
= 'base'¶ The string identifier for the controller.
-
parser_options
= {}¶ Additional keyword arguments passed when
ArgumentParser.add_parser()
is called to create this controller sub-parser. WARNING: This could break things, use at your own risk. Useful if you need additional features from Argparse that is not built into the controller Meta-data.
-
stacked_on
= 'base'¶ A label of another controller to ‘stack’ commands/arguments on top of.
-
stacked_type
= 'embedded'¶ Whether to embed commands and arguments within the parent controller’s namespace, or to nest this controller under the parent controller (making it a sub-command). Must be one of
['embedded', 'nested']
.
-
subparser_options
= {}¶ Additional keyword arguments passed when
ArgumentParser.add_subparsers()
is called to create this controller namespace. WARNING: This could break things, use at your own risk. Useful if you need additional features from Argparse that is not built into the controller Meta-data.
-
title
= 'sub-commands'¶ The title for the sub-parser group in help output.
-
usage
= None¶ The text that is displayed at the top when
--help
is passed. Defaults to Argparse standard usage.
-
-
ArgparseController.
_post_argument_parsing
()¶ Called on every controller just after arguments are parsed (assuming that the parser hasn’t thrown an exception). Provides an alternative means of handling passed arguments. Note that, this function is called on every controller, regardless of what namespace and sub-command is eventually going to be called. Therefore, every controller can handle their arguments if the user passed them.
For example:
$ myapp --foo bar some-controller --foo2 bar2 some-command
In the above, the
base
controller (or a nested controller) would handle--foo
, whilesome-controller
would handlefoo2
beforesome-command
is executed.class Base(ArgparseController): class Meta: label = 'base' arguments = [ (['-f', '--foo'], dict(help='my foo option', dest=foo)), ] def _post_argument_parsing(self): if self.app.pargs.foo: print('Got Foo Option Before Controller Dispatch')
Note that
self._parser
within a controller is that individual controllerssub-parser
, and is not the root parserapp.args
(unless you are thebase
controller, in which caseself._parser
is synonymous withapp.args
).
-
ArgparseController.
_pre_argument_parsing
()¶ Called on every controller just before arguments are parsed. Provides an alternative means of adding arguments to the controller, giving more control than using
Meta.arguments
.class Base(ArgparseController): class Meta: label = 'base' def _pre_argument_parsing(self): p = self._parser p.add_argument('-f', '--foo', help='my foo option', dest='foo') def _post_argument_parsing(self): if self.app.pargs.foo: print('Got Foo Option Before Controller Dispatch')
-
ArgparseController.
_setup
(app)¶ See IController._setup().
-
class
-
class
cement.ext.ext_argparse.
expose
(hide=False, arguments=[], **parser_options)¶ Bases:
object
Used to expose functions to be listed as sub-commands under the controller namespace. It also decorates the function with meta-data for the argument parser.
Parameters: - hide (
boolean
) – Whether the command should be visible. - arguments – List of tuples that define arguments to add to this commands sub-parser.
- parser_options (
dict
) – Additional options to pass to Argparse.
Usage:
from cement.ext.ext_argparse import ArgparseController, expose class Base(ArgparseController): class Meta: label = 'base' # Note: Default functions only work in Python > 3.4 @expose(hide=True) def default(self): print("In Base.default()") @expose( help='this is the help message for my_command', aliases=['my_cmd'], # only available in Python 3+ arguments=[ (['-f', '--foo'], dict(help='foo option', action='store', dest='foo')), ] ) def my_command(self): print("In Base.my_command()")
- hide (