Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the Python exception hierarchy

Python offers an extensive list of built-in exceptions.

It appears to me that most of the built-in exceptions are intended to be raised only by the interpreter or by Python's built-in functions.

So, which of these built-in exceptions should be raised in user code? Does the guidance differ between Python 2.7 and 3.x?

Coming from .NET, I believed this to be an important question. For .NET, Microsoft provides explicit guidance for what exceptions to throw and not to throw in Using Standard Exception Types.

For Python, it seems to me intuitively and from examples that I have seen that the following built-in exceptions would be appropriate to raise in user code:

IndexError
LookupError
NotImplementedError
TypeError
ValueError

...but these would not as each indicates a type of system failure:

ArithmeticError
    FloatingPointError
    OverflowError
    ZeroDivisionError
MemoryError
OSError
like image 975
DavidRR Avatar asked Apr 07 '26 00:04

DavidRR


1 Answers

The Python programmer is given a lot of flexibility with respect to exceptions that can be raised from user code. However, that flexibility doesn't mean that "anything goes." From the version 3 documentation for the Python standard library, the article 5. Built-in Exceptions offers this general guidance.

On what exceptions a programmer can raise:

User code can raise built-in exceptions. This can be used to test an exception handler or to report an error condition “just like” the situation in which the interpreter raises the same exception; but beware that there is nothing to prevent user code from raising an inappropriate error. (emphasis mine)

On programmer-defined exceptions:

The built-in exception classes can be subclassed to define new exceptions; programmers are encouraged to derive new exceptions from the Exception class or one of its subclasses, and not from BaseException. More information on defining exceptions is available in the Python Tutorial under User-defined Exceptions.

Clause 5.1. Base classes suggests that base class exceptions should not typically be raised:

The following exceptions are used mostly as base classes for other exceptions.

BaseException, Exception, ArithmeticError, BufferError, LookupError

Instead, per the guidance in Clause 5.2. Concrete exceptions, it is concrete exceptions that should typically be raised:

The following exceptions are the exceptions that are usually raised.

AssertionError, AttributeError, EOFError, ... OSError, ..., ZeroDivisionError

So, for instance, instead of raising ArithmeticError, consider raising one of its derived classes: FloatingPointError, OverflowError, and ZeroDivisionError. (Or, perhaps a class that you derive from ArithmeticError.)

(And see clause 5.2.1. OS exceptions for more on OSError.)

And finally, on warning messages from the article 29.5. warnings — Warning control:

Warning messages are typically issued in situations where it is useful to alert the user of some condition in a program, where that condition (normally) doesn’t warrant raising an exception and terminating the program. For example, one might want to issue a warning when a program uses an obsolete module.

...

User code can define additional warning categories by subclassing one of the standard warning categories. A warning category must always be a subclass of the Warning class.

like image 167
DavidRR Avatar answered Apr 09 '26 15:04

DavidRR