Should except handlers save/restore the prior value of the capture variable instead of deleting it?

What’s confusing about

e = 1
try:
    ...
except Exception as e:
    ...
print(e)

Isn’t that e isn’t 1, as that follows normal assignment / scoping rules in Python as once a variable is assigned in the same scope to something else but then the new assignment is deleted it doesn’t magically return to it’s previous assignment. What’s confusing is that e isn’t an instance of Exception as the delete at the end of an exception block is special, it doesn’t happen during other assignments which involve a block, e.g. for and with.

Now I know the reasoning for why this happens, pretty much every developer at some points hits this UnboundLocalError and eventually finds the relevant docs.

If there is a “special” solution to this I would strongly argue it is that this exception is somehow made special to tell you about the implicit delete or give you a link to the documentation and not some new weird scoping rule special to Exceptions.

Scoping is already hard to accurately mentally model[1] and it seems it’s going to get harder with PEP 695[2] and PEP 649 in Python 3.12 and 3.13 respectively, but at least they are solving difficult problems and making Python systemically better rather than solving a mild nuisance the first time you some across it. My 2 cents anyway.


[1]. https://github.com/gvanrossum/gvanrossum.github.io/blob/main/formal/scopesblog.md
[2]. https://discuss.python.org/t/please-consider-delaying-or-even-rejecting-pep-695

2 Likes