[New-bugs-announce] [issue46330] Simplify the signature of __exit__
report at bugs.python.org
Mon Jan 10 08:08:08 EST 2022
New submission from Jelle Zijlstra <jelle.zijlstra at gmail.com>:
With Irit's recent changes (bpo-45711), the (typ, exc, tb) tuple is now always redundant with just exc. As a result, `__exit__` methods now should only need to accept a single argument. If we were designing the context manager protocol from scratch, we could do:
def __exit__(self, exc: BaseException | None, /):
if exc is not None:
print("an exception occurred")
Instead of the current cumbersome three-parameter `__exit__`.
But we're not designing it from scratch, and we need to deal with lots of existing code with three-parameter `__exit__` methods.
One possible decision is that we keep the existing signature, because the cost of changing it is too high. However, this would needlessly complicate learning Python for all future new users.
Here's a possible migration approach:
- When the interpreter encounters a `with` statement, it does `getattr(cm, "__enable_single_parameter_exit__", False)` on the context manager. If this attribute exists and is truthy, `__exit__` is called with a single parameter; otherwise we keep the current behavior.
- After a few releases, we flip the default, so you have to explicitly set `__enable_single_parameter_exit__ = False` to keep three-parameter `__exit__`. Libraries that still wish to support Python 3.10 and older can use this.
- Eventually, after Python 3.10 reaches EOL, we always use one-parameter `__exit__`.
To help the migration, we can do a few things:
- Linters and type checkers can check for discrepancies in the __exit__ signature.
- In the interpreter, we can provide a custom error message if the number of parameters to `__exit__` is not as expected, nudging the user towards setting `__enable_single_parameter_exit__`.
- In the compiler, we can likely warn if a class body contains three-parameter `__exit__` but doesn't set `__enable_single_parameter_exit__ = False`, or similar discrepancies.
Everything here should apply equally to `__aexit__`.
This will require a PEP if implemented, but I want to first see whether other people think this is worth pursuing at all.
nosy: Jelle Zijlstra, iritkatriel
title: Simplify the signature of __exit__
Python tracker <report at bugs.python.org>
More information about the New-bugs-announce