Exception hierarchy
corebeginnerEvery exception is a class inheriting from BaseException. Exception is one direct subclass of it, and almost everything you catch — ValueError, KeyError, OSError — descends from Exception, not BaseException directly.
Think of it as
The hierarchy is a filing cabinet, not a flat pile of error names — BaseException is the cabinet itself, Exception is the drawer for "things your code should normally handle," and SystemExit/KeyboardInterrupt/GeneratorExit sit outside that drawer on purpose, so a catch-all for Exception never accidentally intercepts Ctrl+C or sys.exit().
What we're doing: Confirm where three common exceptions sit in the hierarchy, and show that except Exception does not catch KeyboardInterrupt.
- 1
- Exception.__bases__ shows Exception inherits directly from BaseException — one level up.
- 3
- KeyboardInterrupt is NOT a subclass of Exception, so except Exception below cannot match it.
- 7
- The first except that matches wins — KeyboardInterrupt skips except Exception entirely and is caught by except BaseException instead.
(<class 'BaseException'>,)
True
False
caught by except BaseExceptionWhy this works: issubclass(KeyboardInterrupt, Exception) is False because KeyboardInterrupt inherits BaseException directly, bypassing the Exception drawer entirely — this is why except Exception: is safe to use as a broad catch-all without also swallowing Ctrl+C or sys.exit().
- BaseException — the true root — every exception inherits from here
- Exception — the drawer for ordinary, handleable errors
- ArithmeticError / LookupError / OSError — broad groups within Exception
- ZeroDivisionError / KeyError / FileNotFoundError — the specific errors you actually catch
Catching BaseException instead of Exception for a general handler
Wrong
Better
What you see: Pressing Ctrl+C to stop the program does nothing — the handler silently catches KeyboardInterrupt and the job keeps running, because BaseException includes it.
Why: except BaseException matches every exception, including the three that exist specifically so operators can interrupt a program (KeyboardInterrupt) or a program can exit cleanly (SystemExit). A broad handler almost always means except Exception, which leaves those two paths untouched.
The core of the built-in hierarchy
Together
Remember: except Exception excludes SystemExit/KeyboardInterrupt on purpose. Reach for BaseException only when you truly mean everything.
See also: try except · custom exceptions · multiple exception types

