From: Christian Herdtweck Date: Fri, 15 Jun 2018 09:06:02 +0000 (+0200) Subject: Create new arparse_helpers with NonExitingParser and existing_file X-Git-Tag: v1.3~16 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=410f61384001f423a45ca79f6049cffaa7d15a62;p=pyi2ncommon Create new arparse_helpers with NonExitingParser and existing_file --- diff --git a/src/argparse_helpers.py b/src/argparse_helpers.py new file mode 100644 index 0000000..e18a1c2 --- /dev/null +++ b/src/argparse_helpers.py @@ -0,0 +1,81 @@ +# The software in this package is distributed under the GNU General +# Public License version 2 (with a special exception described below). +# +# A copy of GNU General Public License (GPL) is included in this distribution, +# in the file COPYING.GPL. +# +# As a special exception, if other files instantiate templates or use macros +# or inline functions from this file, or you compile this file and link it +# with other works to produce a work based on this file, this file +# does not by itself cause the resulting work to be covered +# by the GNU General Public License. +# +# However the source code for this file must still be made available +# in accordance with section (3) of the GNU General Public License. +# +# This exception does not invalidate any other reasons why a work based +# on this file might be covered by the GNU General Public License. + +""" +argparse_helpers: Some convenience helpers for argparse + +Featuring +- NonExitingParser: a subclass of ArgumentParser that does not do sys.exit(2) + on parse error but instead raises a ArgParserWantsExit exception. +- function existing_file which can be used as a type in add_argument() calls + +.. codeauthor:: Intra2net +""" + +from argparse import ArgumentParser, ArgumentTypeError +from os.path import isfile + + +class ArgParserWantsExit(Exception): + """ + Exception raised from NonExitingParser instead of calling sys.exit(2). + """ + + def __init__(self, message): + super(ArgParserWantsExit, self).__init__("Error parsing args: " + + message) + + +class NonExitingParser(ArgumentParser): + """ArgumentParser that does not call sys.exit(2) on parse failure. + + Calling sys.exit also just raises a SystemExit exception. But that is not + a subclass of Exception and not as explicit and specific as this one. + + Convenient e.g. for global try-except blocks e.g. in a daemon:: + + def main(): + log = None + try: + log = create_log() + parser = NonExitingParser() + # ... add args ... + args = parser.parse_args() + # ... rest of your program ... + except Exception as exc: + log.error('uncaught exception: exc') # will always show in log + + """ + def error(self, message): + """Called when error occurred parsing args. Raise error, not exit.""" + raise ArgParserWantsExit(message) + + +def existing_file(filename): + """ + Function that raises ArgumentTypeError if argument is not an existing file. + + Returns filename if it is valid. Can be used as `type` argument in + :py:meth:`argparse.ArgumentParser.add_argument` + + If you want to open the file, you can as well use the python built-in + :py:class:`argparse.FileType` instead. + """ + if isfile(filename): + return filename + raise ArgumentTypeError('{} is not an existing file'.format(filename))