Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it recommended to derive from Exception instead of BaseException class in Python?

The Python 2 documentation says that "programmers are encouraged to derive new exceptions from the Exception class or one of its subclasses, and not from BaseException". Without any further explanation as to why.

I am curious as to why it is recommended this way? Is it just to preserve the exceptions hierarchy as Python developers envisioned it?

>>> dir(BaseException) == dir(Exception)
True
like image 789
golem Avatar asked Jan 17 '15 01:01

golem


1 Answers

Exceptions derived from BaseException are: GeneratorExit, KeyboardInterrupt, SystemExit.

According to the documentation:

  • GeneratorExit: Raised when a generator‘s close() method is called. It directly inherits from BaseException instead of StandardError since it is technically not an error.
  • KeyboardInterrupt: Raised when the user hits the interrupt key (normally Control-C or Delete). During execution, a check for interrupts is made regularly. Interrupts typed when a built-in function input() or raw_input() is waiting for input also raise this exception. The exception inherits from BaseException so as to not be accidentally caught by code that catches Exception and thus prevent the interpreter from exiting.
  • SystemExit: The exception inherits from BaseException instead of StandardError or Exception so that it is not accidentally caught by code that catches Exception. This allows the exception to properly propagate up and cause the interpreter to exit.

So the usual reasons are to prevent try ... except Exception accidently prevent interpreter exit (except GeneratorExit)

UPDATE after seeing Ashwini Chaudhary's comment:

PEP 352 - Required Superclass for Exceptions explains the reason.

With the exception hierarchy now even more important since it has a basic root, a change to the existing hierarchy is called for. As it stands now, if one wants to catch all exceptions that signal an error and do not mean the interpreter should be allowed to exit, you must specify all but two exceptions specifically in an except clause or catch the two exceptions separately and then re-raise them and have all other exceptions fall through to a bare except clause:

except (KeyboardInterrupt, SystemExit):
    raise
except:
    ...

That is needlessly explicit. This PEP proposes moving KeyboardInterrupt and SystemExit to inherit directly from BaseException.

like image 193
falsetru Avatar answered Oct 22 '22 23:10

falsetru