On Apr 16, 2015, at 06:09, Steven D'Aprano <steve@pearwood.info> wrote:
Second and more conceptually, it makes sense to think about exception handling in the context of a with-block.
No more than any other block of code. There is nothing special about with blocks that go with exception handling, any more than (say) indexing into a list, processing a dict, or importing a module.
I think the key insight behind this is that a context manager is in some sense equivalent to a try/finally--and can in fact be implemented that way using @contextmanager. That isn't true for any of the other cases. Which also implies that there is "one true answer" to your initial question; the implicit try-equivalent comes after the __enter__. Nevertheless, I see your point, and I think you're right. This interpretation is clearly not obvious and universal (given that you didn't see it that way...). And anyone who _doesn't_ intuitively equate the context manager to the equivalent a try/finally is just as likely to expect either semantics as the other, and therefore it will be a bug magnet and/or a readability issue. (To use it safely, it's not sufficient for _you_ to understand the intended semantics, but for all of your possible readers, after all.)