Steven Bethard wrote:
On Tue, Sep 29, 2009 at 1:31 PM, Paul Moore
wrote: 2009/9/28 Yuvgoog Greenle
: 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