Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python using argparse with cmd

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.

like image 402
DeaconDesperado Avatar asked Oct 05 '12 16:10

DeaconDesperado


1 Answers

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.

like image 79
Naglis Avatar answered Sep 22 '22 10:09

Naglis