[Python-Dev] PEP 389: argparse - new command line parsing module

Michael Haggerty mhagger at alum.mit.edu
Wed Sep 30 06:36:42 CEST 2009


Steven Bethard wrote:
> On Tue, Sep 29, 2009 at 1:31 PM, Paul Moore <p.f.moore at gmail.com> wrote:
>> 2009/9/28 Yuvgoog Greenle <ubershmekel at gmail.com>:
>>> 1. There is no chance of the script killing itself. In argparse and optparse
>>> exit() is called on every parsing error (btw because of this it sucks to
>>> debug parse_args in an interpreter).
> [...]
> 
> This is behavior that argparse inherits from optparse, but I believe
> it's still what 99.9% of users want.  If you're writing a command line
> interface, you don't want a stack trace when there's an error message
> (which is what you'd get if argparse just raised exceptions) you want
> an exit with an error code. That's what command line applications are
> supposed to do.
> 
> If you're not using argparse to write command line applications, then
> I don't feel bad if you have to do a tiny bit of extra work to take
> care of that use case. In this particular situation, all you have to
> do is subclass ArgumentParser and override exit() to do whatever you
> think it should do.
> 
>>> 2. There is no chance the parser will print things I don't want it to print.
> [...]
> 
> There is only a single method in argparse that prints things,
> _print_message(). So if you want it to do something else, you can
> simply override it in a subclass. I can make that method public if
> this is a common use case.

Instead of forcing the user to override the ArgumentParser class to
change how errors are handled, I suggest adding a separate method
ArgumentParser.parse_args_with_exceptions() that raises exceptions
instead of writing to stdout/stderr and never calls sys.exit().  Then
implement ArgumentParser.parse_args() as a wrapper around
parse_args_with_exceptions():

class ArgparseError(Exception):
    """argparse-specific exception type."""
    pass

class ArgumentError(ArgparseError):
    # ...

class ArgumentParser(...):
    # ...
    def parse_args_with_exceptions(...):
       # like the old parse_args(), except raises exceptions instead of
       # writing to stdout/stderr or calling sys.exit()...

    def parse_args(self, *args, **kwargs):
        try:
            self.parse_args_with_exceptions(*args, **kwargs)
        except ArgparseError as e:
            self.print_usage(_sys.stderr)
            self.exit(status=2,
                      message=(_('%s: error: %s\n') % (self.prog, e,)))
        # perhaps catch other exceptions that need special handling...

    def error(self, message):
        raise ArgparseError(message)

The exception classes should hold enough information to be useful to
non-command-line users, and obviously contain error messages that are
output to stderr by default.  This would allow non-command-line users to
call parse_args_with_exceptions() and handle the exceptions however they
like.

Michael


More information about the Python-Dev mailing list