I’ve already quoted @njs in the discussion about PEP 707 but I think his piece of insight is even more relevant for this discussion
So new users constantly try to write their own enter /exit methods […] and I think literally every person who’s ever tried this has gotten it wrong (mostly around exception handling details). At this point we don’t even try to debug; we just tell users to always use @contextmanager.
From a usability standpoint I think a single generator based __with__
inspired by @contextmanager
instead of a pair of __enter__
/__exit__
methods would be a clear usability improvement in addition to yielding (pun intended) a very natural syntax for a few features that the current context manager protocol lacks:
- skipping the enclosed code block (already mentioned above)
- accessing a value returned by the block from the context manager
def __with__(self):
if some_condition:
return # early return means the enclosed block is skipped
try:
...
# binds 'self' to the name captured by the `as` clause
# and receives any value returned from the block
# into the variable 'block_return_value'
block_return_value = yield self
except:
...
else:
... # potentially do stuff with 'block_return_value' here
finally:
...