I cannot think of a real world example just now, but I know that on several occasions I have wanted this. Consider the following contrived example:
# x: list, tuple, dict
# y: str, int
try:
try:
position = y
x[position] = 0
except TypeError:
try:
position = int(y)
x[position] = 0
except ValueError:
raise Exception(f"Invalid insert position {y}")
except TypeError:
position = min(position, len(x))
x = x[:position] + (0,) + x[position+1:]
except IndexError:
position = len(x)
x.append(0)
Yes, it’s stupid but more than stupid, its ugly. Nested try-excepts can be confusing, and cause repetition if the outer handling needs to be used in the inner handling. And what’s more, even in this silly example I would say that encapsulating each try-except into functions isn’t obviously better.
I think it would be nicer to have a way of continuing the previous try block i.e. continue the handling from the “outer” try block.
I have two ideas for this:
1: Parse try inline after an except as return to previous try block i.e.
# x: list, tuple, dict
# y: str, int
try:
position = y
x[position] = 0
except TypeError try:
position = int(y)
x[position] = 0
except ValueError:
raise Exception(f"Invalid insert position {y}")
except TypeError:
position = min(position, len(x))
x = x[:position] + (0,) + x[position+1:]
except IndexError:
position = len(x)
x.append(0)
I would limit the usefulness of this to where having the handling that is in the inner try blocks in the outer try block is safe. Obviously in cases where that is not true this would not allow for removing of nesting. But maybe those cases should not be flattened anyway.
2: Add way to alias try blocks, continue them under new aliases and reference them in excepts i.e.
# x: list, tuple, dict
# y: str, int
try as main_try:
position = y
x[position] = 0
except TypeError:
position = int(y)
x[position] = 0
continue main_try as inner_try
except ValueError in inner_try:
raise Exception(f"Invalid insert position {y}")
except TypeError in inner_try:
position = min(position, len(x))
x = x[:position] + (0,) + x[position+1:]
except IndexError:
position = len(x)
x.append(0)
This would allow for all manner of nested try-excepts to be flattened and made possibly clearer. Both approaches would not break old code, since they are additive changes, and would allow for what I think can be simpler, more readable code in many cases.