Python Exceptions

Exceptions are a type of data in Python used to inform programmers about errors. A simple example of an exception is division by zero. If you run a program like this:

z = 100 / 0

it will terminate with an error:

Traceback (most recent call last):
  File "", line 1, in 
ZeroDivisionError: division by zero

ZeroDivisionError is the exception name, and division by zero is its brief description. Python also tells you the line number where this exception occurred.

Other exceptions are possible. For example, when trying to add a string and a number:

z = 2 + '1'

a TypeError exception will occur:

Traceback (most recent call last):
  File "", line 1, in 
TypeError: unsupported operand type(s) for +: 'int' and 'str'

In this example, a TypeError exception is generated. The hints provide complete information about where the exception was generated and what it is related to.

Let’s look at the hierarchy of built-in Python exceptions, although you may encounter others since programmers can create their own exceptions.

  • BaseException — the base exception from which all others originate.
  • SystemExit — generated by the sys.exit function when exiting a program.
  • KeyboardInterrupt — generated when the program is interrupted by the user (usually with Ctrl+C).
  • GeneratorExit — generated when the close method of a generator object is called.
  • Exception — where purely system exceptions end and ordinary ones begin, which can be worked with.
  • StopIteration — generated by the built-in next function if there are no more elements in the iterator.
  • ArithmeticError — arithmetic error.
  • FloatingPointError — generated during a failed floating-point operation. Rarely encountered in practice.
  • OverflowError — occurs when the result of an arithmetic operation is too large to represent. Does not appear during normal work with integers (since Python supports long numbers), but may occur in some other cases.
  • ZeroDivisionError — division by zero.
  • AssertionError — expression in the assert function is false.
  • AttributeError — object does not have the specified attribute (value or method).
  • BufferError — operation related to the buffer cannot be performed.
  • EOFError — function encountered the end of the file and could not read what it wanted.
  • ImportError — failed to import a module or its attribute.
  • LookupError — incorrect index or key.
  • IndexError — index is out of the range of elements.
  • KeyError — non-existent key (in a dictionary, set, or other object).
  • MemoryError — not enough memory.
  • NameError — no variable found with that name.
  • UnboundLocalError — reference made to a local variable in a function, but the variable is not defined earlier.
  • OSError — system-related error.
  • BlockingIOError
  • ChildProcessError — failure during an operation with a child process.
  • ConnectionError — base class for exceptions related to connections.
  • BrokenPipeError
  • ConnectionAbortedError
  • ConnectionRefusedError
  • ConnectionResetError
  • FileExistsError — attempt to create a file or directory that already exists.
  • FileNotFoundError — file or directory does not exist.
  • InterruptedError — system call interrupted by an incoming signal.
  • IsADirectoryError — a file was expected, but it’s a directory.
  • NotADirectoryError — a directory was expected, but it’s a file.
  • PermissionError — insufficient access rights.
  • ProcessLookupError — the specified process does not exist.
  • TimeoutError — the waiting time has expired.
  • ReferenceError — attempt to access an attribute with a weak reference.
  • RuntimeError — occurs when an exception does not fall under any other category.
  • NotImplementedError — occurs when abstract class methods require overriding in subclasses.
  • SyntaxError — syntax error.
  • IndentationError — incorrect indentation.
  • TabError — mixing tabs and spaces in indentation.
  • SystemError — internal error.
  • TypeError — operation applied to an object of inappropriate type.
  • ValueError — function receives an argument of the correct type but an inappropriate value.
  • UnicodeError — error related to encoding/decoding unicode in strings.
  • UnicodeEncodeError — exception related to unicode encoding.
  • UnicodeDecodeError — exception related to unicode decoding.
  • UnicodeTranslateError — exception related to unicode translation.
  • Warning — Base class for warning exceptions. This family of exceptions represents various categories of warnings.
  • BytesWarning — Warnings related to potential issues when working with bytes. This category of warnings is used in cases of potential errors when working with bytes (bytes and bytearray).
  • DeprecationWarning — Category of warnings about functionality that is undesirable to use. This category is usually used to indicate that some part of the functionality is obsolete (perhaps it has been replaced by a more advanced one) and is not recommended for use.
  • FutureWarning — Category describing warnings about future changes. Warnings of this category are intended to notify about upcoming semantic changes. Example of a warning about upcoming changes from numpy:FutureWarning: comparison to 'None' will result in an elementwise object comparison in the future.
  • ImportWarning — warning about a potential error when importing a module. Warnings of this category can be used, for example, in cases of changes to the import system using interceptors (hooks).
  • PendingDeprecationWarning — Category of warnings about functionality that will soon become undesirable to use.
  • ResourceWarning — Warnings related to potential issues when working with resources. An example of using this category of warnings might be indicating the need to close a socket, which is necessary to free up resources.
  • RuntimeWarning — Warning about questionable behavior during execution. The category can be used to indicate questionable application behavior, for example, if the code has identified likely inaccuracies in calculations.
  • SyntaxWarning — Warning about the use of questionable syntactic constructs. The category is used in cases where likely syntactic errors are detected.
  • UnicodeWarning — Warnings related to potential issues when working with Unicode.
  • UserWarning — Class for user warnings. Can be used by users as a base class for creating their own warning hierarchies.

Now, knowing when and under what circumstances exceptions can occur, we can handle them. The try — except construct is used for handling exceptions.

The first example of using this construct:

try:
    k = 1 / 0
except ZeroDivisionError:
    k = 0
print(k)
0

In the try block, we execute an instruction that may generate an exception, and in the except block, we catch them. Both the exception itself and its descendants are caught. For example, by catching ArithmeticError, we also catch FloatingPointError, OverflowError, and ZeroDivisionError.

try:
    k = 1 / 0
except ArithmeticError:
    k = 0
print(k)
0

There is also an except instruction without arguments, which catches everything (including keyboard interruptions, system exits, etc.). Therefore, in this form, the except instruction is practically not used, and except Exception is used instead. However, exceptions are most often caught one by one to simplify debugging (in case you make another mistake, and except catches it).

Two more instructions related to our problem are finally and else. Finally executes a block of instructions in any case, whether there was an exception or not (applicable when something must be done, for example, closing a file). The else instruction is executed if there was no exception.

f = open('1.txt')
ints = []
try:
    for line in f:
        ints.append(int(line))
except ValueError:
    print('This is not a number. Exiting.')
except Exception:
    print('What is this?')
else:
    print('Everything is fine.')
finally:
    f.close()
    print('I closed the file.')
    # Exactly in this order: try, group of except, then else, and only then finally.
This is not a number. Exiting.
I closed the file.