Sobes.tech
Junior

Tell us about the exception hierarchy in Python.

sobes.tech AI

Answer from AI

In Python, exceptions are organized into a hierarchical tree, with the root being the class BaseException.

Main branches and classes:

  • BaseException: The base class for all exceptions. Not intended for direct catching in most cases.
    • SystemExit: Raised when the program exits, for example, by calling sys.exit().
    • KeyboardInterrupt: Generated when the user interrupts program execution (usually Ctrl+C).
    • GeneratorExit: Occurs when a generator is closed.
    • Exception: The base class for most handled exceptions. It is usually caught in except blocks.
      • StopIteration: Raised by an iterator to signal that there are no more items.
      • ArithmeticError: The base class for errors in arithmetic operations.
        • FloatingPointError: Error in floating-point operations (rare).
        • OverflowError: The result of an arithmetic operation is too large.
        • ZeroDivisionError: Division by zero.
      • AssertionError: Error when an assert fails.
      • AttributeError: Accessing a non-existent attribute of an object.
      • EOFError: End of file reached without reading data.
      • ImportError: Error importing a module/name.
        • ModuleNotFoundError: Module not found.
      • LookupError: The base class for errors when searching by key/index.
        • IndexError: Invalid index in a sequence.
        • KeyError: Invalid key in a dictionary.
      • NameError: Using an undefined variable/name.
        • UnboundLocalError: Accessing a local variable before assignment.
      • OSError: Errors related to the operating system (files, processes, etc.). Includes many subclasses.
        • FileNotFoundError: File or directory not found.
        • IsADirectoryError: A file was expected, but a directory was found.
        • NotADirectoryError: A directory was expected, but a file was found.
        • PermissionError: Access error (e.g., no read/write permissions).
        • ProcessLookupError: The process with the specified PID does not exist.
        • TimeoutError: The operation exceeded the set time limit.
      • RuntimeError: Errors not falling under other RuntimeWarning categories.
        • RecursionError: Maximum recursion depth exceeded.
      • SyntaxError: Syntax error in code.
        • IndentationError: Incorrect indentation.
      • SystemError: Internal Python interpreter error.
      • TypeError: Operation applied to an object of inappropriate type.
      • ValueError: Operation received an argument of the correct type but with an invalid value.
      • RuntimeWarning: Runtime warning (not an exception, but often related).
      • ... (many others, specific to modules or situations)

When catching exceptions, except blocks are processed from top to bottom. It is important to catch more specific exceptions before their base classes to avoid catching them unintentionally.

Example:

# Catching a more specific exception before the base
try:
    # Code that may raise an exception
    d = {"a": 1}
    print(d["b"])
except KeyError:
    # Handling missing key
    print("Error: Key not found.")
except LookupError:
    # Handling general search errors (includes KeyError and IndexError)
    print("Error: Problem with element lookup.")
except Exception as e:
    # Handling any other exceptions
    print(f"Another error occurred: {e}")

If except LookupError was placed before except KeyError, the KeyError would be caught by the base class.

Tell us about the exception hierarchy in Python… - sobes.tech