Even good programmers make mistakes sometimes. You can divide an integer by zero by mistake or miss a bracket when working with lists. Python handles these cases pretty well, it usually doesn't lead to unexpected bugs. But if they happen, the built-in exceptions are raised. In this topic, we are going to present a detailed description of built-in exceptions. Specifically, we'll look at SyntaxError, TypeError, OSError and ValueError in this topic.
Hierarchy of Exceptions
We should note that all built-in exceptions have a hierarchy, some of the exceptions in the hierarchy may lead to more specific exceptions. Take a look at the full structure of the built-in exceptions:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- BaseExceptionGroup
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ExceptionGroup [BaseExceptionGroup]
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- EncodingWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
Don't be afraid, we know, it's hard to remember the hierarchy at once. You can do it step-by-step when you have free time. Below we try to focus on the main features of the structure you need to know.
First of all, remember that the BaseException class is a base class for all built-in exceptions, which we can consider as the root of all exceptions. This exception is never raised on its own and should be inherited by other exception classes. In terms of this hierarchy, other classes are known as subclasses of the root class. For instance, the IndexError is a subclass of the LookupError class. At the same time, the LookupError itself is a subclass of the Exception class.
The BaseException subclasses include SystemExit, KeyboardInterrupt, GeneratorExit and Exception.
The
SystemExitis raised when thesys.exit()function is used to terminate the program.The
KeyboardInterruptis raised when the user hits the interrupt key, e.g.Ctrl+Cduring the execution of a program.The
GeneratorExitappears when your generator is being closed (it will be covered later).The most common subclass is the
Exceptionclass. It contains all exceptions that are considered as errors and warnings.
Built-in Exceptions Types
Before we start analyzing the pieces of code, take a look at the table with the built-in exceptions that programmers often meet in their code:
Exception | Explanation |
| Raised when a statement uses the wrong syntax. |
| Raised when any operation/function is applied to an object of inappropriate type. |
| Raised when any operation/function accepts an argument with an inappropriate value. |
| Raised when a system function returns a system-related error. |
| Raised when the imported library is not found. |
| Raised when such built-in functions as |
| Raised when a local or global name is not found. |
| Raised when a sequence subscript is out of range. |
Now, let's shed some more light on them! We'll check some of them in a later topic.
SyntaxError
The first error is the SyntaxError. Take a look at the first example:
new_list = [1, 2, 3, 4, 5
print(new_list)
# File "main.py", line 2
# print(new_list)
# ^
# SyntaxError: invalid syntax
The list doesn't have the right-side bracket ], that's why the SyntaxError is raised. Below is another example:
i := 3
# File "<stdin>", line 1
# i := 3
# ^
# SyntaxError: invalid syntax
The expression is wrong and Python tells us about it by raising SyntaxError.
The SyntaxError is generally very easy to fix: you should make sure that all brackets, commas, quotation marks are in place and that everything is syntactically correct in the line that the error points out.
TypeError
Now let's observe a TypeError:
a = 'Python' + 25
print(a)
# Traceback (most recent call last):
# File "main.py", line 1, in <module>
# a = 'Python' + 25
# TypeError: can only concatenate str (not "int") to str
We tried to concatenate a string and an integer, that's why the TypeError was raised. This can happen to you while solving coding tasks on the platform. For example, if you read input and forget to convert it into an integer before performing some operations:
num = input()
print(num / 100)
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# TypeError: unsupported operand type(s) for /: 'str' and 'int'
To get rid of this error, check that you perform operations on variables of the correct data type.
ValueError
In the code below, the input accepts a string that can't be converted to an integer, that's why the ValueError is raised:
user_input = input('Enter an integer: ') # you enter 'cat' here
a = int(user_input)
print(a)
# Traceback (most recent call last):
# File "main.py", line 1, in <module>
# a = int(user_input)
# ValueError: invalid literal for int() with base 10: 'cat'
This error may also occur with a list:
cats = ['Tommy', 'Timmy', 'Ram']
cats.remove('Alex')
print(cats)
# Traceback (most recent call last):
# File "main.py", line 2, in <module>
# cats.remove('Alex')
# ValueError: list.remove(x): x not in list
The method remove() can't delete the specified string from the list because there's no such element there.
The ValueError can be caused by various reasons. The general advice is to read the error message and check that the function can process the given object.
OSError
The next example illustrates the OSError. Some subclasses of this error may appear when you work with files. For example, if we try to open a file that doesn't exist, the FileNotFoundError will be raised:
f = open('i_dont_exist.txt')
# Traceback (most recent call last):
# File "main.py", line 1, in <module>
# f = open('i_dont_exist.txt')
# FileNotFoundError: [Errno 2] No such file or directory: 'i_dont_exist.txt'
Of course, there are a lot of other examples when the OSError and its subclasses can be raised.
When an OSError occurs, the reason for it is stated in the description.
Summary
So far, we highlighted some important issues dedicated to the built-in exceptions:
we reviewed the hierarchy of exceptions;
we learned what classes and subclasses stand for;
we analyzed some built-in exceptions and discussed the way around them.
If you are keen on reading more information, check the Built-in Exceptions part of the official documentation. For now, let's proceed to the comprehension tasks and applications to strengthen your knowledge!