On Sun, 17 Nov 2019 at 19:18, Oscar Benjamin email@example.com wrote:
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.
The context here has been lost - I've searched the thread and I can't find a proper explanation of how open() "misbehaves" in any way that seems to relate to this statement (I don't actually see any real explanation of any problem with open() to be honest). There's some stuff about what happens if open() itself fails, but I don't see how that results in a problem (as opposed to something like a subtle application error because the writer didn't realise this could happen).
Can someone restate the problem please?