sys.exit(1) vs raise SystemExit vs raise

Martin A. Brown martin at linux-ip.net
Tue Apr 12 19:05:34 EDT 2016


Hello all,

Apologies for this post which is fundamentally, a 'me too' post, but 
I couldn't help but chime in here.

>This is good practice, putting the mainline code into a ‘main’ 
>function, and keeping the ‘if __name__ == '__main__'’ block small 
>and obvious.
>
>What I prefer to do is to make the ‘main’ function accept the
>command-line arguments, and return the exit status for the program::
>
>    def main(argv):
>        exit_status = EXIT_STATUS_SUCCESS
>        try:
>            parse_command_line(argv)
>            setup_program()
>            run_program()
>        except SystemExit as exc:
>            exit_status = exc.code
>        except Exception as exc:
>            logging.exception(exc)
>            exit_status = EXIT_STATUS_ERROR
>
>        return exit_status
>
>    if __name__ == '__main__':
>        exit_status = main(sys.argv)
>        sys.exit(exit_status)
>
>That way, the ‘main’ function is testable like any other function: 
>specify the command line arguments, and receive the exit status. 
>But the rest of the code doesn't need to know that's happening.

This is only a riff or a variant of what Ben has written.  Here's what I like
to write:

  def run(argv):
      if program_runs_smoothly:
          return os.EX_OK
      else:
          # -- call logging, report to STDERR, or just raise an Exception
          return SOMETHING_ELSE

  def main():
      sys.exit(run(sys.argv[1:]))
  
  if __name__ == '__main__':
      main()

Why do I do this?

  * the Python program runs from CLI because [if __name__ == '__main__']
  * I can use main() as an entry point with setuptools
  * my unit testing code can pass any argv it wants to the function run()
  * the run() function never calls sys.exit(), so my tests can see what WOULD
    have been the process exit code

The only change from what Ben suggests is that, once I found os.EX_OK, I just
kept on using it, instead of difining my own EXIT_SUCCESS in every program.

Clearly, in my above example the contents of the run() function look strange.
Usually it has more different kinds of stuff in it.

Anyway, best of luck!

-Martin

-- 
Martin A. Brown
http://linux-ip.net/


More information about the Python-list mailing list