ExceptionGroup split partitions matching leaf exceptions while preserving the nesting needed to locate those failures.
Python ExceptionGroup split: retain the nested failure structure
Operation contract
The import batch contains one amount error at the root and another inside a row group beside an I/O failure. Splitting ValueError extracts both amount leaves. The remainder retains the I/O leaf inside its row group. A recursive summarizer visits leaves for the displayed type list; it does not flatten the groups being handled. The original group still owns all three exception objects after the split.
Failure and ownership boundary
Handling the matching subgroup does not handle the remainder. Raising the residual group is one possible policy; logging it and pretending the entire batch succeeded is not. A custom subclass may need derive to preserve its extra fields. This example partitions ordinary Exception leaves; it does not put KeyboardInterrupt or cancellation into an ExceptionGroup. Python ExceptionGroup: handle selected failures and retain the rest and Python exception interview: chained causes and a finally return that hides failure cover the surrounding call boundary.
Working program
def leaf_types(failure):
if isinstance(failure, BaseExceptionGroup):
return [name for child in failure.exceptions for name in leaf_types(child)]
return [type(failure).__name__]
batch = ExceptionGroup("import", [ValueError("amount"),
ExceptionGroup("row", [OSError("read"), ValueError("identifier")])])
matched, residual = batch.split(ValueError)
print("matched:", leaf_types(matched))
print("residual:", leaf_types(residual))
print("original:", leaf_types(batch))
print("nested remainder:", isinstance(residual.exceptions[0], ExceptionGroup))Output
matched: ['ValueError', 'ValueError']
residual: ['OSError']
original: ['ValueError', 'OSError', 'ValueError']
nested remainder: TrueCosts and limits
Partitioning visits the exception tree and retains references to its matching leaves. This fixture has bounded depth; deeply nested externally constructed groups need a traversal-depth policy. Exception messages and attached tracebacks can retain sensitive values and large object graphs.
Common Mistakes
- Do not mark the entire batch handled after processing only one subgroup.
- A leaf summary is a reporting view, not the original nested error structure.
Connected lessons
Python ExceptionGroup: handle selected failures and retain the rest, Python exceptions: translate an input error without hiding its cause, Python asyncio TaskGroup: cancel sibling work and retain failure evidence.
