Search code examples
pythoncommand-line-argumentsargument-passingargparse

Don't stop executing a function when called with -h


My main python functions accepts argv and calls two other functions with these arguments to set up the whole application.

The issue is that if argv includes -h (`--help) then it is passed to the first function, it prints it's usage message (generated by argparse) as expected, like below:

optional arguments:
  -h, --help       show this help message and exit
  -x section

but then execution is stopped!, and we are back at the prompt.

I would like the execution to continue so the second function is also called, and its usage message also gets printed. Does anyone know how this can be achieved?


Solution

  • You need to catch the SystemExit exception:

    exited = None
    try:
         function1(argv)
    except SystemExit as e:
         # don't exit just yet
         exited = e
    function2(argv)
    
    # If function 2 *did not* exit, there was a legitimate reason
    # re-raise the SystemExit exception
    if exited is not None:
        raise exited
    

    Note that I store the system exit exception raised in function1; it could be that it was raised as a result of a different action, not the -h flag. If function2 doesn't raise an exception itself, we re-raise the original SystemExit exception to clean up properly.

    The except SystemExit as e: statement captures the exception in a local variable e. The local variable thus assigned is normally deleted at the end of the except block (to prevent a reference cycle); if you want to use that exception outside of the except suite you need to store it in a new variable; this is why exited is a separate variable defined outside of the except suite.

    Alternatively, you can opt to remove the -h switch from the function1 argparser altogether by using the add_help=False option, then handling help manually there.