[Python-ideas] with-except-finally blocks
Kale Kundert
kale at thekunderts.net
Thu Apr 16 08:39:37 CEST 2015
Hello everyone,
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 [1] try-with [2]
============== ======== ============
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%)
[1]: grep -Po '^\s*with .*:' **/*.py
[2]: 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?
-Kale Kundert
More information about the Python-ideas
mailing list