Issue 21067: Support Multiple finally clauses. (original) (raw)

Created on 2014-03-25 22:44 by kevincox, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (4)
msg214861 - (view) Author: Kevin Cox (kevincox) Date: 2014-03-25 22:44
I think it would be useful to support multiple finally clauses. The idea would be that each clause would be run, even if prior clauses throw exceptions. The idea came when hunting a bug in the Mozilla test suite. The code looked like as follows. try: resource1 = allocateresource1() resource2 = allocateresource2() dostuffthatmightthrowexception() finally: if resource1: resource1.close() if resource2: resource2.close() The problem is that if resource1,close() throws an exception resource2 is not closed. The alternative looks like this. try: resource1 = allocateresource1() try: resource2 = allocateresource2() dostuffthatmightthrowexception() finally: if resource2: resource2.close() finally: if resource2: resource2.close() Or it could look like this. try: resource1 = allocateresource1() resource2 = allocateresource2() dostuffthatmightthrowexception() finally: try: if resource1: resource1.close() finally: if resource2: resource2.close() Both of which exhibit indentation explosion when there are a number of resources that need to be cleaned up. If multiple finally clauses were allowed the code would be much more readable and would look as follows. try: resource1 = allocateresource1() resource2 = allocateresource2() dostuffthatmightthrowexception() finally: if resource1: resource1.close() finally: if resource2: resource2.close()
msg214862 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2014-03-25 22:54
For resource management, it would be more idiomatic to use context managers, either with multiple CMs in one with-statement or, dynamically, with contextlib.ExitStack. For test suites using unittest, there is also the addCleanup functionality of the TestCase. (And if another test framework is used, it might have something similar, or maybe should grow it.) Anyway, such changes are not decided upon in the tracker. If you think this should go forward please discuss it on the python-ideas list. For it to go forward a PEP will likely need to be written.
msg214879 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2014-03-26 03:58
And for this particular case, even if the resource allocators don't support the context manager protocol, contextlib.closing can do the job: from contextlib import closing with closing(allocateresource1()) as resource1, closing(allocateresource2()) as resource2: dostuffthatmightthrowexception() If it's not a simple as calling close, you can write your own simple manager wrapper that calls some other cleanup function use @contextlib.contextmanager.
msg214881 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2014-03-26 08:05
> If you think this should go forward please discuss it > on the python-ideas list. For it to go forward a PEP > will likely need to be written. I concur with this assessment. Marking this as closed.
History
Date User Action Args
2022-04-11 14:58:00 admin set github: 65266
2014-03-26 08:05:15 rhettinger set status: open -> closednosy: + rhettingermessages: + resolution: rejected
2014-03-26 03:58:27 josh.r set nosy: + josh.rmessages: +
2014-03-25 22:59:46 jcea set nosy: + jcea
2014-03-25 22:54:47 georg.brandl set nosy: + georg.brandlmessages: +
2014-03-25 22:44:17 kevincox create