On 4/8/21 2:40 PM, Chris Angelico wrote:
At least in this form, it's clear that there's a sharp distinction between the stuff around the outside of the 'with' block and the stuff inside it.
The semantics, as suggested, give 'with' blocks two distinct exception-management scopes, which mostly but do not entirely overlap. It's not a problem to rigorously define the semantics, but as evidenced here, people's intuitions will vary depending on which context manager is being used. It's absolutely obvious that the OP's example should let you catch errors from open(), and equally obvious that suppressing BaseException should mean that nothing gets caught. That's the problem here.
As such, I'm -0.5 on this. It's a kinda nice feature, but all it really offers is one less indentation level, and the semantics are too confusing.
I, on the other hand, would love for something along those lines -- I find it massively annoying to have to wrap a with-block, which is supposed to deal with exceptions, inside a try/except block, because the exceptions that `with` deals with are too narrowly focused.
Of course, I also prefer
def positive(val): "silly example" if val > 0: return True else: return False
def positive(val): "silly example" if val > 0: return True return False
because the first more clearly says "either this happens, or that happens". Likewise, having the excepts line up with the `with` visually ties the code together.
Granted, this mostly boils down to personal preference.