Inheriting from BaseException vs Exception

Viewed 1955

I know what is difference between Exception and BaseException in Python. I wonder what is a good practice and more pythonic: Should my exceptions inherit from BaseException or Exception?

1 Answers

By default, all user-defined exceptions should inherit from Exception. This is recommended in the documentation:

exception Exception

All built-in, non-system-exiting exceptions are derived from this class. All user-defined exceptions should also be derived from this class.

This is also recommend by and motivated in PEP 8:

Derive exceptions from Exception rather than BaseException. Direct inheritance from BaseException is reserved for exceptions where catching them is almost always the wrong thing to do.


In general, exceptions deriving from Exception are intended to be handled by regular code. In contrast, exceptions deriving directly from BaseException are associated with special situations; handling them like normal exceptions can lead to unexpected behaviour. This is why an idiomatic "catch all" handler only handles Exception:

def retry(func):
    while True:
        try:
            return func()
        except Exception as err:
            print(f"retrying after {type(err)}: {err}")

Builtin exceptions inheriting directly from BaseException currently are KeyboardInterrupt, SystemExit, and GeneratorExit which are associated with shutdown of the program, thread or generator/coroutine. Incorrectly handling them will prevent a graceful shutdown.

Note that while the default should be to inherit from Exception, it is fine to inherit from BaseException if there is a good reason to do so. For example, asyncio.CancelledError also inherits from BaseException since it represents shutdown of asyncio's thread equivalent, the Task.

Related