This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author JelleZijlstra
Recipients JelleZijlstra, iritkatriel
Date 2022-01-10.13:08:07
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1641820088.08.0.801223860673.issue46330@roundup.psfhosted.org>
In-reply-to
Content
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.
History
Date User Action Args
2022-01-10 13:08:08JelleZijlstrasetrecipients: + JelleZijlstra, iritkatriel
2022-01-10 13:08:08JelleZijlstrasetmessageid: <1641820088.08.0.801223860673.issue46330@roundup.psfhosted.org>
2022-01-10 13:08:08JelleZijlstralinkissue46330 messages
2022-01-10 13:08:07JelleZijlstracreate