I'd like to propose a little bit of syntactic sugar: allowing with-blocks to be followed by except- and finally-blocks just like try-blocks. For example:
with open('spam.txt') as file: print(file.read()) except IOError: print('No spam here...') finally: print('done.')
This proposed syntax is semantically equivalent to wrapping a with-block within a try-block like so:
try: with open('spam.txt') as file: print(file.read()) finally: print('done.') except IOError: print('No spam here...')
I see two advantages to the proposed syntax. First and most obviously, it saves an extra line and an extra indentation level. One line may not be a big deal, but one indentation level can really affect readability. Second and more conceptually, it makes sense to think about exception handling in the context of a with-block. More often than not, if you're using a with-block, you're expecting that something in that block could throw an exception. Usually with-blocks are used to make sure resources (e.g. files, database sessions, mutexes, etc.) are properly closed before the exception is propogated. But I very often want to do some custom clean-up as well (alert the user, etc.). Currently that requires wrapping the whole thing in a try-block, but allowing with-blocks to behave as try-blocks is a more direct way to express what is meant.
I was curious how often with-blocks are actually wrapped in try-blocks for no other purpose than catching exceptions raised in the with-block. So I searched through a number of open source projects looking (roughly) for that pattern:
Project with  try-with  ============== ======== ============ django 230 17 ipython 541 8 matplotlib 112 3 moinmoin 10 0 numpy 166 1 pillow/pil 1 0 pypy 254 4 scipy 163 2 sqlalchemy 36 0 twisted 72 1 ============== ======== ============ total 1585 36 (2.27%)
: grep -Po '^\s*with .*:' **/*.py : grep -Poz 'try:\s*with .*:' **/*.py
Assuming these projects are representative, about 2% of the with-blocks are directly wrapped by try-blocks. That's not a huge proportion, but it clearly shows that this pattern is being used "in the wild". Whether or not it's worth changing the language for the benefit of 2% of with-blocks is something to debate though.
What do people think of this idea?