kabanus kabanus - 1 month ago 7
Python Question

Always perform finally block except for one exception

I have a

try:finally
block that must execute always (exception or not) unless a specific exception occurs. For the sake of argument let's say it's a
ValueError
, so I'm asking if I can implement:

try:
stuff()
except Exception as e:
if type(e) is ValueError: raise
#do important stuff
raise

#do important stuff


in a more elegant fashion to skip copy-pasting
#importantstuff
. If I ruled Python it would look something like:

try:
stuff()
finally except ValueError:
#do important stuff


Putting
#importantstuff
in a function is not an answer, but not possible is.

Answer

If you need finally to skip things in specific conditions, you'll need to use an explicit flag:

do_final_stuff = True
try:
    # ...
except ValueError:
    do_final_stuff = False
    raise
finally:
    if do_final_stuff:
        # ...

You could also use a context manager here, to clean up afterwards. A context manager is passed the current active exception if there is one:

class MyContextManager:
    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, tb):
        if exc_type is not ValueError:
            # do cleanup

with MyContextManager():
    # ...