Is that any more ambiguous than for...else? On Thu, Apr 16, 2015 at 2:22 AM, Andrew Barnert < abarnert@yahoo.com.dmarc.invalid> wrote:
On Apr 15, 2015, at 23:39, Kale Kundert <kale@thekunderts.net> wrote:
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...')
Why does the finally come before the except? Also, it's still indented with the with, which means you seem to be defining with-except-finally in terms of with-finally, and not defining with-finally at all. Did you mean to have the finally after the except and dedented?
Anyway, I like the idea, but does the grammar work? A with that has an optional except and finally at the same level seems potentially ambiguous. For example:
with spam: pass with eggs: pass finally: pass
If you think about it, it's pretty obvious that the finally goes with the second with, not the first. But can the parser tell that? Or a human who's scanning the code rather than thinking carefully about it? Or tools like auto-indenters?
(I think this problem doesn't arise for try, because it must have at least except or finally.)
It should be easy to edit the grammar and build the parser to at least the first part of the question; for the last part, trying to hack up a few different external tools like Emacs python-mode. But for the human question, I'm not sure how to answer it quite so easily...
I see two advantages to the proposed syntax. First and most obviously,
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
it saves 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
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- Ryan [ERROR]: Your autotools build scripts are 200 lines longer than your program. Something’s wrong. http://kirbyfan64.github.io/