The Many Ways to Exit in Python
It’s fundamentally useful to exit your program when it’s done. Here are five(!) ways to do so in Python.
We can exit from Python code by raising a
print("Done.") raise SystemExit()
The top level interpreter catches this special exception class and triggers its exit routine. This includes such steps as running all
atexit functions, deleting all objects, and finally calling the OS exit function.
SystemExit optionally takes an integer for the exit code, where 0 represents success and any other value represents failure. We can use this to signal calling programs that an error occurred:
print("Woops.") raise SystemExit(1)
(When Python crashes with an exception, it uses an exit code of 1.)
If you’re looking for a quick answer, you can stop reading here. Use
raise SystemExit(<code>) as the obviousest way to exit from Python code and carry on with your life.
More obscurely, we can pass
SystemExit any object, in which case Python will print the
str() of that object to stderr and return an exit code of 1:
This can be handy, but I’d argue being explicit is clearer:
print("Woops.", file=sys.stderr) raise SystemExit(1)
We can also call
sys.exit() to exit Python, optionally with an exit code:
import sys sys.exit(1)
Underneath this only does
raise SystemExit(<arg>) (in C).
sys.exit() is a little less typing than
raise SystemExit(), it does require the import, which is a bit inconvenient. Also it hides the detail that an exception is raised.
quit() are “extra builtins” added by Python’s
site module. Both essentially call
raise SystemExit(), optionally with an exit code, like:
This looks super convenient! We don’t need to import anything, and the names are very short.
Unfortunately, the site module is optional. We can be skip loading it by running Python with the
-S flag. In which case our call to
exit() can still exit, but with a
$ python -S -c 'exit(1)' Traceback (most recent call last): File "<string>", line 1, in <module> NameError: name 'exit' is not defined
quit() are optional, I’d recommend avoiding using them in your programs. But they’re fine to use at the REPL, which is why they exist. They even print usage information when written without brackets, to help new users trying to exit the REPL:
>>> exit Use exit() or Ctrl-D (i.e. EOF) to exit
That message leads us to...
Ctrl-D is the universal keyboard shortcut for exit. It sends EOF (End of File) to the current program, telling it the user is done sending input and it should exit.
Ctrl-D works with every command line program, including
python. So it’s best to learn this shortcut, rather than use the Python-specific
exit(). Then you can exit
sqlite, and any other command line program, without giving it a second thought.
os._exit(n) function exits Python immediately with the given exit code
n. It does so by calling the underlying OS exit function directly.
os._exit() prevents Python from running its normal exit process. This is very destructive and usually undesirable, hence the “private/danger” underscore prefx.
The only reason I’ve found for calling
os._exit() is when debugging in cases where raising
SystemExit doesn’t work. For example, in a thread, raising
SystemExit does not exit the progarm - it only stops the thread. Directly calling
os._exit() can stop the entire program, which can be combined with a few well-placed debug prints to inspect state.
So, it’s worth knowing that
os._exit() exists, although you should avoid it in day-to-day life.
os._exit() is a thin wrapper around our OS’ underlying exit function. We can call this function directly through Python’s
ctypes module. This doesn’t confer any advantage - in fact it’s worse, because our code won’t work on all OS’s. But it’s cool to know about.
On Linux/macOS/other Unixes, the exit function is available in the C standard library as
exit(). We see its details by running
man 3 exit - the Linux man page is online here. We can call it with
ctypes like so:
from ctypes import CDLL from ctypes.util import find_library libc = CDLL(find_library("libc")) libc.exit(1)
Thanks to Anthony Sottile for the tip to use
raise SystemExit(...) in this video.
I hope you have found the exit you’re looking for,
Learn how to make your tests run quickly in my book Speed Up Your Django Tests.
One summary email a week, no spam, I pinky promise.