New submission from Jelle Zijlstra <jelle.zijls...@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:

class CM:
    def __enter__(self):
        return self
    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.

----------
messages: 410210
nosy: Jelle Zijlstra, iritkatriel
priority: normal
severity: normal
status: open
title: Simplify the signature of __exit__

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue46330>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to