On Sun, 17 Nov 2019 at 06:28, Random832
On Sat, Nov 16, 2019, at 16:13, Greg Ewing wrote:
I seem to remember we had such a context manager for a brief time after the with-statement was invented, until someone had the bright idea to make open() do double duty.
The main source of confusion I foresee if we re-introduce it, is that people are now used to doing 'with open()...', so we either make open() no longer a context manager and break existing code, or have two ways to do it, with the one that is currently the most widely used one having a subtle trap hidden in it.
I wonder if a general mechanism for turning badly behaved context manager factories into nice ones would be a useful addition to contextlib. something like this:
That might be useful but it doesn't solve the problem from the perspective of someone writing context manager utilities like nested because it still leaves a trap for anyone who uses open with those utilities. Also I don't know of any other misbehaving context managers besides open so I'm not sure that a general utility is needed rather than just a well-behaved alternative for open. PEP 343 gives the example of "opened" which doesn't have this problem https://www.python.org/dev/peps/pep-0343/#examples but apparently that didn't make it to the final release of 2.5 (I guess that's what Greg is referring to). Ultimately the problem is that the requirements on a context manager are not clearly spelled out. The with statement gives context manager authors a strong guarantee that if __enter__ returns successfully then __exit__ will be called at some point later. There needs to be a reverse requirement on context manager authors to guarantee that it is not necessary to call __exit__ whenever __enter__ has not been called. With the protocol requirements specified in both directions it would be easy to make utilities like nested for combining context managers in different ways. -- Oscar