Hierarchy of Exceptions in Python

The Python programming language provides us with an extensive and myriad of exception classifications. The idea behind this classification is to make it easy for us to figure out the nature of the triggered exception so that we can debug it easily. 

Let’s say, for instance, any operating system problem would be classified under the group ‘OSError’ exception. While on the other hand, any math-related problem would be put into the ‘ArithmeticError’ group.

Python conveniently also classifies error groups into subcategories, like how ArithmeticError can further be classified into ZeroDivisionError which only deals with division by zero incidents. 

These groupings of classes and subclasses are what we call the Hierarchy of Exceptions in Python. 

When you look at it, it can broadly be categorized into 2 levels.

The first level just consists of BaseException, Exception, and its subclasses. That looks like this:

As we can see, each class covers a unique “reason behind an error”.

For instance, the class Exception is used to contain all exceptions that we encounter on a day-to-day basis as Python programmers.

The same logic is applied to the subclasses. The exception group Warning (which is derived from Exception) contains all sorts of warnings, hence it acts like a base class for all official Python warnings. 

The second level compromises of all the classes in the first level coupled with all its subclasses and their subclasses. In simple words, here are all the exception classes in one diagram:

Wow, pretty big right? This comprehensive diagram displays the complete Python hierarchy structure! 

As you may have noticed, the hierarchy levels are denoted by the colors used. We can see how all the classes are systematically classified, this helps programmers understand exceptions and ultimately helps in debugging their code.

Here’s a short explanation of all the exceptions:

BaseException: This is the base class for any built-in exception. It is not meant to be directly inherited by user-defined classes and is rarely used directly in code.

BaseExceptionGroup: The BaseExceptionGroup class extends BaseException and it can wrap any exception.

GeneratorExit: Although technically not an error, it’s raised when a generator’s exit() function is called.

KeyboardInterrupt: Raised when the user interrupts the program by pressing ctrl+c or del on the keyboard. The exception inherits from BaseException so as to not be accidentally caught by code that catches Exception and thus prevent the interpreter from exiting.

Read all the ways you can exit a program here!

SystemExit: Used to exit the program by the user when the function sys.exit() is triggered. This is also inherited from BaseException instead of Exception so that it is not accidentally caught by code that catches Exception.

Here is a short diagram explaining what happens if SystemExit is raised!

Exception: Base class for all built-in, non-system-exiting exceptions. Every user-defined exception should also be derived from this class.

This article talks about the Exception class in great detail and I highly recommend you read it!

ArithmeticError: The base class for all arithmetically related exceptions.

FloatingPointError: Raised when a float calculation fails.

OverflowError: This is raised when an arithmetic operation results in too big of a number to be represented.

ZeroDivisionError: Raised when the second argument of a division or modulo operation is zero. In other words, it’s raised when attempting to divide/mod a number by zero.

Do you know how to handle a ZeroDivisionError?

AssertionError: Raised when an assert statement fails.

AttributeError: Raised when an attribute reference or assignment fails. This happens when you try to access or change a property (attribute) of an object, but that property doesn’t exist in the first place itself.

Here’s a guide on troubleshooting AttributeError!

BufferError: This is triggered when a buffer-related operator cannot be performed.

EOFError: Raised when the input() function encounters an unexpected ‘end-of-file’ situation. In simple words, this happens when you’re reading something from a file and you reach the end before you expected to.

ExceptionGroup [BaseExceptionGroup]: It extends the Exception group and can wrap subclasses of the Exception class. The ExceptionGroup constructor raises a TypeError if any contained exception is not an Exception subclass.

ImportError: As the name states, this is raised when there is some problem trying to import a module.

Related: 6 Common Mistakes While Importing Modules & Their Fixes! (Python)

ModuleNotFoundError: A subclass of the ImportError, this is raised by the import statement when a module cannot be located. This is usually because the module does not exist itself.

Here’s an article that covers everything that you need to know about ModuleNotFoundError.

LookupError: Base class for the group of exceptions that are raised when the key or index used on a mapping or sequence is invalid. i.e it is like a parent class to errors that occur when you try to access something in a data structure, that does not exist. For example, trying to access a non-existent item from a list.

IndexError: A subclass of the LookupError, it is raised when you try to access an index out of range. For example, if there are 4 elements in a list and you try to access the 7th element.

KeyError: This is also a subclass of the LookupError. It is triggered when a dictionary key is not found in the set of existing keys. For example, if a dictionary has the keys; key1, key2, and key3 only. And then if you try to access a key called key4, which does not exist, this error will be triggered.

Click here to learn more about KeyError.

MemoryError: It is raised when the interpreter cannot allocate enough memory for your program to execute. In other words, the system doesn’t have sufficient RAM available to run our program.

NameError: Raised when an identifier (whether it’s a variable or a function) is not found in the local or the global scope.

Learn how to troubleshoot NameError here.

UnboundLocalError: This is a subclass of the NameError. It’s raised when a reference has been made to a local variable in a function or method, but no value has been bound to that variable. For example, when you try to access a variable before assigning a value to it.

OSError: The base class for all the operating system related exceptions. It is also raised when a system call returns a system-related error, including I/O failures.

BlockingIOError: Raised when an operation would block on an object that is set for non-blocking operation.

ChildProcessError: Raised when a child process encounters an error.

ConnectionError: Base class for all connection-related issues. All network connection-related subclasses must be derived from here.

BrokenPipeError: Derived from ConnectionError, it is used to raise when trying to write on a pipe while the other end has been closed. In other words, it’s raised when writing to a broken pipe.

ConnectionAbortedError: Also derived from ConnectionError. It’s raised when a connection attempt is aborted by the peer. This means that when you try to connect with another party and they abort the connection instead.

ConnectionRefusedError: Another subclass of ConnectionError. This is raised when a connection attempt is refused by the peer. This means that when you try to connect with another party, instead they refuse to establish a connection.

ConnectionResetError: A subclass of ConnectionError. It’s raised when a connection attempt is reset by the peer. In other words, it means that when you try to connect with another party, and that party resets the connection instead of connecting with you.

FileExistsError: A subclass of the OSError. It is triggered whenever you try to create a file or a directory that already exists.

FileNotFoundError: This on the other hand is used when you try to access a file or a directory that does not exist. It is also a subclass of the OSError.

Become an expert on FileNotFoundError by reading this article.

InterruptedError: Derived from the OSError class, it is raised when a system call is interrupted by an incoming signal.

IsADirectoryError: This is triggered when a file operation is requested on a directory. For instance, if you try to open a directory (instead of a file) and read its contents, this error will be raised appropriately. The IsADirectoryError is derived from the OSError class.

NotADirectoryError: Another subclass of the OSError.  It is the opposite of the IsADirectoryError, it is raised when you try to perform a directory operation on anything that is not a directory.

PermissionError: Raised when you do not have sufficient permissions to open a file. It is a subclass of the OSError class.

ProcessLookupError: Raised when a given process doesn’t exist or when a process lookup fails. It is derived from the OSError class.

TimeoutError: Final subclass of the OSError. Raised when a system function is timed out at the system level.

ReferenceError: Raised when a weak reference proxy, created by the weakref.proxy() function, is used to access an attribute of the referent that has already been garbage collected.

RuntimeError: This is the base class for runtime-related exceptions. Also raised when an error is detected that doesn’t fall into any of the other categories. The RuntimeError is also the default error for the raise statement.

NotImplementedError: A child class of the RuntimeError, it is raised when an abstract method is not implemented.

RecursionError: Last derived class of the RuntimeError. It is triggered when your program exceeds the maximum recursion depth. In simple words, if you have a function that keeps calling itself too many times, it will run out of memory and trigger this error.

StopAsyncIteration: It is raised by the __anext__() method of an asynchronous iterator object to stop an asynchronous iteration.

StopIteration: This error is triggered when the built-in function next() and an iterator’s __next__() raises it to signal the end of an iteration.

SyntaxError: It is raised when the parser encounters a SyntaxError in the code. In simple words, it is triggered when you break the syntactical rules of the Python programming language.

SyntaxError: A Step By Step Troubleshooting Guide!

IndentationError: A subclass of the SyntaxError. This is raised when there is an incorrect indentation in the code. It can be used as the base class for all incorrect indentation incidents. Here’s an example.

TabError: A subclass of the IndetationError used to raise when your indentation contains an inconsistent use of tabs and spaces.

SystemError: Raised when the Python interpreter has found out that an internal error has occurred. You should report this to the author or maintainer of your Python interpreter.

TypeError: This is a common error that is raised whenever there has been an attempt to perform an operation or a function on an object of the wrong type. For example, trying to divide a number with a string will result in a TypeError.

Read this article to become familiar with TypeError.

ValueError: The ValueError is raised whenever an operator or a function receives an argument of the right type but the wrong value. 

Here’s a helpful guide on ValueError

UnicodeError: This is the base class for warnings related to Unicode. The UnicodeError class is also a subclass of the ValueError class. Here’s an example of the error in action.

UnicodeDecodeError: A subclass of the UnicodeError. It is raised when the Unicode decoding operation fails.

UnicodeEncodeError: A subclass of the UnicodeError. It is raised when the Unicode encoding operation fails.

UnicodeTranslateError: A subclass of the UnicodeError. It is raised when the Unicode translating operation fails.

Warning: This is the base class for all the warning-related exceptions in Python.

Note: All the following classes are subclasses derived from the Warning class

BytesWarning: Base class for warnings related to bytes and bytearray.

DeprecationWarning: Used to warn that a feature is deprecated and might be removed in the future.

EncodingWarning: This warning is related to issues with encodings.

FutureWarning: Raised to warn about deprecated features that will change behavior in the future. These warnings are intended for end users of applications that are written in Python.

ImportWarning: Raised for probable mistakes that are related to importing modules.

PendingDeprecationWarning: This is used as a warning to notify that a feature has become obsolete or useless and will be deprecated in the future. This is usually used when the deprecation is unusual, otherwise the DeprecationWarning is normally used.

ResourceWarning: Class that gives warnings for resource-usage related issues.

RuntimeWarning: Class for warnings about uncertain runtime behavior.

SyntaxWarning: Class for warnings about dubious syntax. These syntax issues are non-critical as they are caught before the execution of the code.

UnicodeWarning: Raised for warnings whenever there are any issues related to Unicode.

UserWarning: Class for warnings generated by user code. All user-related warnings must be derived from this class.

For the next step in your Python journey I invite you to master some of the most common errors you will run into in your daily life as a Python developer. We have compiled a list of just 7 exceptions that you need to focus on if you wish to gain mastery of Exceptions in Python!

7 Most Common In-Built Exceptions in Python!

If you are a visual learner here is a YouTube video that we made on that same topic!

And with that, let’s end this article.

Kudos to you on making it to the end of the article, not many have the patience to do so!

I hope you enjoyed reading this article and found this article helpful!

Feel free to share it with your friends and colleagues!

If your thirst for knowledge has not been quenched yet, here are some related articles that might spark your interest!

Related Articles

“Exception” Class in Python: A Walk-through!

Python: How to Create a Custom Exception

7 Most Common In-Built Exceptions in Python!

Python: Details contained in an Exception

Thanks to Namazi Jamal for his contributions in writing this article!

Reference

Python official documenation

Photo of author
Editor
Balaji Gunasekaran
Balaji Gunasekaran is a Senior Software Engineer with a Master of Science degree in Mechatronics and a bachelor’s degree in Electrical and Electronics Engineering. He loves to write about tech and has written more than 300 articles. He has also published the book “Cracking the Embedded Software Engineering Interview”. You can follow him on LinkedIn