An exception breaks out of normal control flow, and is handled by a surrounding block or
by a block further up the call stack (Language Reference 4.3). Python uses the
termination model: a handler can find out what happened and continue at an outer level,
but cannot resume the operation that failed. An unhandled exception ends the program,
and a traceback is printed unless it is SystemExit.
The exception hierarchy
Every exception is an instance of a class derived from
BaseException. Programs should normally derive from, and catch,
Exception, which leaves out the exit signals.
BaseException
├── BaseExceptionGroup
├── GeneratorExit
├── KeyboardInterrupt
├── SystemExit
└── Exception
├── ArithmeticError
│ ├── FloatingPointError
│ ├── OverflowError
│ └── ZeroDivisionError
├── AssertionError
├── AttributeError
├── BufferError
├── EOFError
├── ExceptionGroup [BaseExceptionGroup]
├── ImportError
│ ├── ImportCycleError
│ └── 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
│ ├── PythonFinalizationError
│ └── RecursionError
├── StopAsyncIteration
├── StopIteration
├── SyntaxError
│ └── IndentationError
│ └── TabError
├── SystemError
├── TypeError
├── ValueError
│ └── UnicodeError
│ ├── UnicodeDecodeError
│ ├── UnicodeEncodeError
│ └── UnicodeTranslateError
└── Warning
├── BytesWarning
├── DeprecationWarning
├── EncodingWarning
├── FutureWarning
├── ImportWarning
├── PendingDeprecationWarning
├── ResourceWarning
├── RuntimeWarning
├── SyntaxWarning
├── UnicodeWarning
└── UserWarning
IOError and EnvironmentError are aliases of
OSError (PEP 3151, Python 3.3). A new exception class usually inherits
from Exception:
class ConfigError(Exception):
def __init__(self, path):
super().__init__(f"bad config in {path}")
self.path = path
The raise statement
raise_stmt: "raise" [expression ["from" expression]]
| Form | Effect |
|---|---|
raise E("message") | Raises an instance |
raise E | Instantiates the class with no arguments and raises it |
raise | Re-raises the exception being handled. With none, it raises RuntimeError |
raise E from cause | Raises E with an explicit cause |
The expression must be an exception class or instance. Anything else raises
TypeError (7.8).
Handling exceptions
The try statement gives the
syntax and the order of its clauses. An except clause is checked like
this (8.4.1):
- The expression is evaluated when the exception reaches the clause. It matches if the exception is an instance of the class named, or of a subclass.
- It may be a tuple of classes. Since Python 3.14 the parentheses can be dropped if
there is no
asclause (PEP 758):except KeyError, IndexError:. - A bare
except:catches everything, includingKeyboardInterruptandSystemExit, and must be last. - The first matching clause runs and no other does.
try:
value = int(text)
except ValueError as exc:
print("not a number:", exc)
except (TypeError, OverflowError):
print("wrong type")
else:
print("ok", value)
finally:
print("always runs")
else suite and a finally suiteThe name after as is deleted at the end of the clause, to avoid a
reference cycle through the traceback (8.4.1). Assign the exception to another name to
keep it. sys.exception() returns the exception being handled (Python
3.11).
Exception attributes
| Attribute | Meaning |
|---|---|
args | The arguments given to the constructor |
__traceback__ | The traceback object, which is writable |
__cause__ | The explicit cause, set by raise ... from |
__context__ | The exception being handled when this one was raised |
__suppress_context__ | When true, the context is hidden in the traceback |
__notes__ | Notes added with add_note(), created at the first call |
with_traceback(tb) sets the traceback and returns the exception.
add_note(text) adds a note that the standard traceback prints after the
exception (PEP 678, Python 3.11).
Chaining
An exception raised while another is being handled keeps a link to it (PEP 3134, Python 3.0).
| Form | __context__ | __cause__ | __suppress_context__ |
|---|---|---|---|
raise New in a handler | The old exception | None | False |
raise New from old | The old exception, if one is being handled | old | True |
raise New from None | The old exception | None | True |
The traceback shows __cause__ when it is set. It shows
__context__ only if __cause__ is None and
__suppress_context__ is false. from None (PEP 409, Python
3.3) therefore hides the original while keeping it available for debugging.
try:
connect()
except OSError as exc:
raise RuntimeError("could not connect") from exc
try:
value = table[key]
except KeyError:
raise AttributeError(key) from None
Exception groups
An exception group raises several unrelated exceptions together, as concurrent tasks can (PEP 654, Python 3.11).
| Class | Base | May contain |
|---|---|---|
ExceptionGroup | Exception | Subclasses of Exception only |
BaseExceptionGroup | BaseException | Any exception |
BaseExceptionGroup(msg, excs) returns an ExceptionGroup if
every exception fits one. The list of exceptions must not be empty, and groups can be
nested. except Exception catches an ExceptionGroup but not a
BaseExceptionGroup.
| Member | Result |
|---|---|
message, exceptions | The text and the tuple of contained exceptions |
subgroup(condition) | A group of the matching exceptions, or None. The condition is a type, a tuple of types or a callable |
split(condition) | The pair (match, rest) |
derive(excs) | A group with the same message around excs. Subclasses override it |
except*
except* handles only part of a group (8.4.2). Each clause takes the
members that match, and it receives them as a group. Several clauses can run, and any
members left unhandled are raised again as a group at the end.
try:
raise ExceptionGroup("errors", [ValueError(1), TypeError(2), OSError(3)])
except* ValueError as group:
print(group.exceptions) # (ValueError(1),)
except* (TypeError, KeyError) as group:
print(group.exceptions) # (TypeError(2),)
# OSError(3) is raised again in a new ExceptionGroup
- A type is required:
except*:is aSyntaxError. - A
trystatement has eitherexceptorexcept*clauses, not both. break,continueandreturncannot appear in anexcept*clause.except* ExceptionGroupraisesTypeError.- A plain exception that matches a clause is wrapped in a group, so the handler still sees a group. One that matches no clause propagates unchanged.