PEP 707: A simplified signature for __exit__ and __aexit__

__cmp__ and the old buffer protocol were deprecated and no longer supported, but __reduce__ and __getnewargs__ are still supported, alongside with __reduce_ex__ and __getnewargs_ex__. Deprecating __exit__ will harm a lot of people.

Replacing a triple of arguments with a single argument is a weak reason for introducing a new dunder. The first and the third arguments can be derived from the second argument, so it is only a matter of convenience. I do not think that it justifies all drawbacks.

But we can return to it if decide to extend the context manager semantic.

  1. The result of __enter__ can be provided to a user, but it is not accessible in __exit__. For example, one of problems related to implementation of the buffer protocol from Python side is that __enter__ can return an acquired memory view, but __exit__ does not get it back to release it. It may be worth to pass the result of __enter__ as yet one argument to __leave__.

  2. The result of __enter__ can be provided to a user, but in many cases the useful result of the context manager is only available after exiting the with block. Examples are assertRaises() and assertWarns(). The only solution is to return a mutable object, keep the reference to it in the context manager (see (1)), and updating it in __exit__. You cannot return an immutable object. You need to keep a reference. You cannot implement the timeit context manager which return just a time spent to execute the block as a float.

    What if make the result of __leave__ available to a user? Maybe overriding the variable in as, or introducing a new syntax.

I think it should be a separate topic for discussing an extended context manager protocol.

8 Likes