> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Python Exception Group

An `ExceptionGroup` (introduced in Python 3.11 via PEP 654) is a built-in exception type that allows multiple, independent exceptions to be raised and handled simultaneously. It acts as a container that aggregates a sequence of exception instances into a single tree-like structure, enabling the propagation of concurrent errors without suppressing any individual exception.

## Class Hierarchy

The feature introduces two new built-in classes:

* **`BaseExceptionGroup`**: Inherits from `BaseException`. It is instantiated if any exception within the group inherits from `BaseException` but not `Exception` (e.g., `KeyboardInterrupt` or `SystemExit`).
* **`ExceptionGroup`**: Inherits from `BaseExceptionGroup` and `Exception`. It is instantiated only when all contained exceptions are subclasses of `Exception`.

## Instantiation and Raising

An exception group is initialized with a string message and a sequence (typically a list) of exception instances. Groups can be nested to form a tree structure.

```python theme={"dark"}

# Raising a flat ExceptionGroup
raise ExceptionGroup(
    "Multiple validation errors occurred",
    [
        ValueError("Invalid configuration parameter"),
        TypeError("Expected string, got integer")
    ]
)


# Raising a nested ExceptionGroup
raise ExceptionGroup(
    "System failure",
    [
        ConnectionError("Database timeout"),
        ExceptionGroup("File system errors", [PermissionError(), FileNotFoundError()])
    ]
)
```

## Handling with `except*`

To handle exceptions, Python introduces the `except*` syntax. Unlike a standard `except` clause, which matches the exception object as a whole and stops, `except*` can structurally split exception groups and handle multiple branches independently.

```python theme={"dark"}
try:
    # Raising a standard, single exception
    raise ValueError("Single error")
except* ValueError as e:
    # Python automatically wraps the single exception in an ExceptionGroup
    print(type(e))  # <class 'ExceptionGroup'>
    print(e.exceptions)  # (ValueError('Single error'),)

try:
    raise ExceptionGroup(
        "Errors", 
        [
            ValueError("A"), 
            ExceptionGroup("Nested", [TypeError("B"), ValueError("C")])
        ]
    )
except* ValueError as e:
    # Extracts ValueError("A") and ValueError("C") into a new ExceptionGroup tree,
    # preserving the original nested structure.
    pass
except* TypeError as e:
    # Extracts the remaining TypeError("B") into a new ExceptionGroup.
    pass
```

**Mechanics of `except*`:**

1. **Leaf-Node Evaluation:** Exception matching in an `except*` clause is strictly evaluated only on the individual non-group exceptions (the leaves). The matching condition is never evaluated against the `ExceptionGroup` or `BaseExceptionGroup` containers themselves.
2. **Type Restrictions:** Because `except*` matching applies only to leaf nodes, it is a `TypeError` to use `ExceptionGroup`, `BaseExceptionGroup`, or their subclasses as the target type in an `except*` clause.
3. **Splitting and Wrapping:** If leaf exceptions match the specified type, the exception group is structurally split. The matched leaf exceptions are extracted into a new `ExceptionGroup` that preserves the original nested shape, which is then bound to the variable in the `as` clause. If a standard, single exception is caught, Python automatically wraps it in an `ExceptionGroup` before binding it.
4. **Fallthrough:** Any unmatched leaf exceptions remaining in the original group are propagated to subsequent `except*` clauses. If exceptions remain after all `except*` blocks are evaluated, a new `ExceptionGroup` containing the unhandled exceptions is implicitly re-raised.
5. **Exclusivity:** You cannot mix standard `except` and `except*` clauses in the same `try` block.

## Internal API

Exception groups expose specific methods and attributes for programmatic inspection and manipulation:

* **`exceptions`**: A tuple containing the direct child exceptions of the group.
* **`split(condition)`**: Structurally splits the exception group. The `condition` can be an exception type, a tuple of exception types, or a callable that takes an exception instance and returns a boolean. Unlike the `except*` syntax, the condition passed to `split()` **is** evaluated against exception group containers. If the condition returns `True` for an exception group itself, the entire group is included in the match, and its individual child exceptions are not evaluated further. It returns a tuple `(match, rest)`, where `match` is an `ExceptionGroup` containing the exceptions that satisfy the condition, and `rest` is an `ExceptionGroup` containing the remainder. If no exceptions match, `match` is `None`; if all match, `rest` is `None`.
* **`subgroup(condition)`**: Similar to `split()`, but returns only the `match` component (an `ExceptionGroup` or `None`).

```python theme={"dark"}
eg = ExceptionGroup("Errors", [ValueError(1), TypeError(2)])


# Splitting by exception type (or tuple of types)
match_type, rest_type = eg.split(ValueError)

print(type(match_type))  # <class 'ExceptionGroup'> containing ValueError
print(type(rest_type))   # <class 'ExceptionGroup'> containing TypeError


# Splitting by a callable condition
match_cb, rest_cb = eg.split(lambda e: str(e) == "2")
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Python Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
