开发者

exception handling for optparse of python

HI, guys.

I am using cmd and optparse to develop a CLI.py for a collection of already-functional classes (CDContainer, CD, etc.). The following are some parts of the code. I have a problem here. when there are exceptions(wrong input type or missing values), the optparse will exit the whole program instead of the specific command method.

import cmd
class CLI(cmd.Cmd):

    def do_addcd(self, line):
        args=line.split()
        parser = OptionParser()
        parser.add_option("-t", "--track", dest="track_number", type="in开发者_运维百科t",
            help="track number")
        parser.add_option("-n", "--cdname", dest="cd_name", type="string",
            help="CD name")
        (options, positional_args) = parser.parse_args(args[0:])
        cd_obj= CD()
        cd_obj.addCD(options.track_number, options.cd_name)

Under ">python", if I type CLI.py, then I will have (Cmd), so I could type command like "(Cmd)addcd -t 3 -n thriller". but if I type "addcd -t r -n 3", then optparse will terminate the whole CLI.py and exit. This is not good for me. I want to remind the user for each method, instead of terminating the whole program.

however, the optparse documentation says "the whole program exits". so I could not use optparse "blindly". what can I do?


The optparse documentation says this:

If optparse‘s default error-handling behaviour does not suit your needs, you’ll need to subclass OptionParser and override its exit() and/or error() methods.

Ideally you'd define a new type of exception, subclass optparse, raise the exception in the exit() or error() method that you've overridden, and then catch it and deal with it as needed.

You can cheat, though. If you want the error message printed but just don't want the program to exit, then you can catch the SystemExit exception to catch where optparse is trying to exit and stop it.

So, for example:

try:    
    (options, positional_args) = parser.parse_args(args[0:])
except SystemExit:
    return

cd_obj= CD()
cd_obj.addCD(options.track_number, options.cd_name)

or to override the method:

import optparse

class OptionParsingError(RuntimeError):
    def __init__(self, msg):
        self.msg = msg

class OptionParsingExit(Exception):
    def __init__(self, status, msg):
        self.msg = msg
        self.status = status

class ModifiedOptionParser(optparse.OptionParser):
    def error(self, msg):
        raise OptionParsingError(msg)

    def exit(self, status=0, msg=None):
        raise OptionParsingExit(status, msg)

and then:

try:
    parser = ModifiedOptionParser()
    parser.add_option("-t", "--track", dest="track_number", type="int",
        help="track number")
    (options, positional_args) = parser.parse_args(args[0:])
except OptionParsingError, e:
    print 'There was a parsing error: %s' % e.msg
    return
except OptionParsingExit, e:
    print 'The option parser exited with message %s and result code %s' % (e.msg, e.status)
    return

cd_obj= CD()
cd_obj.addCD(options.track_number, options.cd_name)


It probably has to do with the types that you're passing to the CD class: without seeing it, there's a really good chance that it's failing there. Before creating that object and passing the arguments, it's a really good idea to clean that data, ensure it's the correct type, and perform any other checks that you see as being reasonable.


    try:
    parser = ModifiedOptionParser()
    parser.add_option("-t", "--track", dest="track_number", type="int",
        help="track number")
    (options, positional_args) = parser.parse_args(args[0:])
except OptionParsingError, e:
    print 'There was a parsing error: %s' % e.msg
    return
except OptionParsingExit, e:
    print 'The option parser exited with message %s and result code %s' % (e.msg, e.status)
    return

The custom exception class still can't handle '-h --help' option that displays the default help context.

What I did I used sys.argv before try - except block to handle help function.

if sys.argv[1] == '-h' or sys.argv[1] == '--help':
    raise Exception('help')

parser = ModifiedOptionParser()
...
except Exception as value:
    status = str(value)
    if status is 'help':
         parser.print_help()
         return -1    # I need to set different return value

Thanks for the tips by the way.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜