except statement is something I often see in the main loop of a
script that should run indefinitely. Pylint warns you about this problem
W0702: No exception type(s) specified (bare-except)), but in my opinion we
should start to treat this as an error like flake8 does (
E722 do not use bare
Consider the following code snippet:
This will work nicely to keep your program running whatever happends inside you
risky_business function. But let’s try to stop your program by pressing
$ python a.py ^C('Problems?', (<type 'exceptions.KeyboardInterrupt'>, KeyboardInterrupt(), <traceback object at 0x7f234f6c9dd0>))
We caught the
KeyboardInterrupt exception and just carried on. But we catch
more which we should not. Let’s try to exit the program from the business
function, maybe because the user asked for it or we got signaled.
$ python a.py ('Problems?', (<type 'exceptions.SystemExit'>, SystemExit(0,), <traceback object at 0x7f49b7ab5e18>)) ('Problems?', (<type 'exceptions.SystemExit'>, SystemExit(0,), <traceback object at 0x7f49b7ab5ea8>)) ...
So why is this happening? Both
exceptions (derived from
except statement without any
restriction will catch any exception derived from
BaseException. Here is the
complete hierachy of the builtin
We can fix our problem by restricting the kind of exception that we want to catch:
When we press CTRL-C now, the program exits with the right exception.
$ python a.py ^CTraceback (most recent call last): File "a.py", line 10, in <module> risky_business() File "a.py", line 6, in risky_business time.sleep(1) KeyboardInterrupt
Pylint will still warn you about this line, because catching
still very broad and you should only do this when you have a good reason, e.g.
the reason mentioned above (to keep a service running even if it could not
handle a certain input or request).
So next time you see a bare
except statement in your code, take a moment to
reconsider if you really want to catch
GeneratorExit which I did not mention above). If that is the case, you might
want to make it explicit so that the next person reading the code does not have
to check again.