Free Python reference · JavaScript timeline
Python 3.11: Handle grouped failures and inspect errors
Exception groups, structured async tasks, TOML parsing, and more precise tracebacks improve everyday diagnostics.
Released · Editorial review October 25, 2026
Introduced in Python 3.11 · Syntax
ExceptionGroup and except*
An exception group packages several exceptions into one failure. This is useful when independent work can fail in several places. except* selects matching members, including members of nested groups, rather than treating the whole group as a single ordinary exception.
Separate handlers can process different exception types. Each matching handler receives a subgroup; unhandled members continue propagating. Ordinary except ValueError does not mean “find ValueErrors inside this group.”
The example constructs a small flat group so the counts are easy to inspect. In application code, handle only the failures you understand and let unexpected errors remain visible.
Worked example
Minimum Python 3.11
try: raise ExceptionGroup("batch", [ValueError("bad count"), TypeError("bad shape")]) except* ValueError as group: print("value errors:", len(group.exceptions)) except* TypeError as group: print("type errors:", len(group.exceptions))
Expected output
value errors: 1
type errors: 1
Example checked with CPython 3.14.8, CPython 3.15.0, Pyodide Python 3.13.2.
Common mistake
Do not mix except and except* handlers on the same try statement. Handling a matching subgroup does not suppress unrelated exceptions.
Try it yourself
Add a second ValueError and predict the first count. Then consider what propagates if the TypeError handler is removed.
Read more: Python 3.11 release notes · PEP 654
Introduced in Python 3.11 · Standard library
TaskGroup gives related tasks a boundary
An asyncio.TaskGroup owns tasks created within an asynchronous context manager. Leaving the context waits for those tasks. If a task fails with an ordinary exception, the group cancels remaining tasks and reports failures through an exception group after cleanup.
This makes task lifetime explicit: a caller knows when related work has finished. Cancellation remains cooperative, so coroutines must allow it to propagate after any cleanup.
The example gathers two independent results and combines them only after the group exits. Run it as a native script; notebook and browser event loops have their own entry-point rules.
Worked example
Minimum Python 3.11 · Run locally
import asyncio async def twice(number): await asyncio.sleep(0) return number * 2 async def main(): async with asyncio.TaskGroup() as group: first = group.create_task(twice(2)) second = group.create_task(twice(5)) return first.result() + second.result() print(asyncio.run(main()))
Expected output
14
Example checked with CPython 3.14.8, CPython 3.15.0.
Common mistake
TaskGroup does not make CPU-bound work parallel. Swallowing CancelledError can interfere with structured cancellation.
Try it yourself
Make one coroutine raise ValueError. Explain why the combined result should not be used as though every task succeeded.
Read more: Python 3.11 release notes
Introduced in Python 3.11 · Standard library
Read TOML with tomllib
tomllib reads TOML into Python values without an extra package. TOML commonly appears in configuration files such as pyproject.toml. Parsing from a string uses loads; loading from a file uses a binary file object with load.
Parsed integers become integers and sections become dictionaries. Parsing verifies TOML syntax, but it does not prove the configuration has all the fields your application requires. Validate required keys and acceptable values after parsing.
The example uses a string so it needs no filesystem access. The standard module reads TOML; it does not provide a TOML-writing API.
Worked example
Minimum Python 3.11
import tomllib config = tomllib.loads('[report]\nname = "weekly"\nlimit = 5\n') print(config["report"]["name"]) print(config["report"]["limit"] + 1)
Expected output
weekly
6
Example checked with CPython 3.14.8, CPython 3.15.0, Pyodide Python 3.13.2.
Common mistake
Text-mode files are not accepted by tomllib.load(). TOML syntax checks are different from validating the application-specific configuration schema.
Try it yourself
Change limit to a quoted string. Predict which line now fails and where validation should catch that mistake.
Read more: Python 3.11 release notes · PEP 680
Introduced in Python 3.11 · Interpreter capability
Tracebacks can point inside expressions
CPython 3.11 records finer source positions so a traceback can identify a failing subexpression within a longer line. This helps distinguish a missing record field from a problem in a later arithmetic operation.
The exact display depends on the interpreter, terminal, available source text, and configuration. The script below prints the exception type deterministically. To inspect source-position markers, temporarily remove the try/except and run the saved script in a normal terminal.
Use the traceback as a lead, then reduce the failing input and keep a regression case. A highlighted expression does not explain which input rule the program violated.
Worked example
Minimum Python 3.11 · Run locally
record = {"count": None} try: total = record["count"] + 1 except TypeError as error: print(type(error).__name__)
Expected output
TypeError
The printed exception name is tested. Traceback underline/color is a native-interpreter display feature and is not a portable expected-output contract.
Example checked with CPython 3.14.8, CPython 3.15.0.
Common mistake
Do not write tests against exact traceback spacing or color. Catching and ignoring every TypeError can hide unrelated defects.
Try it yourself
Remove the handler and inspect the traceback. Then change record to {} and explain why the failure type changes.
Read more: Python 3.11 release notes · PEP 657
Recap
Exception groups, structured async tasks, TOML parsing, and more precise tracebacks improve everyday diagnostics. Prefer the clearest form that works on your project's supported Python versions.
Read the full Python 3.11 release notes →