Is there a way to use the argparse
module hooked in as the interpreter for every prompt in an interface inheriting from cmd
?
I'd like for my cmd interface to interpret the typical line
parameter in the same way one would interpret the options and arguments passed in at runtime on the bash shell, using optional arguments with -
as well as positional arguments.
Well, one way to do that is to override cmd
's default
method and use it to parse the line with argparse
, because all commands without do_
method in your cmd.Cmd subclass will fall through to use the default
method. Note the additional _
before do_test
to avoid it being used as cmd
's command.
import argparse
import cmd
import shlex
class TestCLI(cmd.Cmd):
def __init__(self, **kwargs):
cmd.Cmd.__init__(self, **kwargs)
self.parser = argparse.ArgumentParser()
subparsers = self.parser.add_subparsers()
test_parser = subparsers.add_parser("test")
test_parser.add_argument("--foo", default="Hello")
test_parser.add_argument("--bar", default="World")
test_parser.set_defaults(func=self._do_test)
def _do_test(self, args):
print args.foo, args.bar
def default(self, line):
args = self.parser.parse_args(shlex.split(line))
if hasattr(args, 'func'):
args.func(args)
else:
cmd.Cmd.default(self, line)
test = TestCLI()
test.cmdloop()
argparse
does a sys.exit
if it encounters unknown commands, so you would need to override or monkey patch your ArgumentParser
's error
method to raise an exception instead of exiting and handle that in the default
method, in order to stay in cmd
's command loop.
I would suggest you look into cliff which allows you to write commands that can automatically be used both as argparse
and cmd
commands, which is pretty neat. It also supports loading commands from setuptools
entry points, which allows you to distribute commands as plugins to your app. Note however, that cliff
uses cmd2
, which is cmd
's more powerful cousin, but you can replace it cmd
as cmd2
was developed as a drop-in replacement for cmd
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With