[Python-Dev] Compilation of "except FooExc as var" adds useless store

Steven D'Aprano steve at pearwood.info
Sun Jan 6 07:10:24 EST 2019


On Sun, Jan 06, 2019 at 01:10:48PM +0200, Paul Sokolovsky wrote:

[...]
> P.S.
> I actually wanted to argue that such an implementation is hardly ideal
> at all. Consider:
> 
> ----
> e = "my precious data"
> try:
>     1/0
> except Exception as e:
>     pass
> 
> # Where's my *global* variable?
> # Worse, my variable can be gone or not, depending on whether exception
> # triggered or not.
> print(e)

That's not "worse", that's BETTER.

With e deleted, you get an immediate exception the moment you try to use 
it, and you *know* something has gone wrong, instead of the program 
continuing, either to fail much later, where it isn't clear why the code 
fails, or worse, not fail at all, but instead silently do the wrong 
thing.

Incorrect code that fails sooner is better than incorrect code that 
fails later, and MUCH better than incorrect code that doesn't fail at 
all.

The real problem here is that if e holds your precious data, why are you 
assigning an exception to e? You probably wouldn't complain that this 
breaks your program:

e = "my precious data"
import sys as e
# where is my data???

or this:

e = "my precious data"
e = None

so why do you expect `except Exception as e` to be different? Its just a 
name binding operation, the same as all the others.

Regardless of the mechanism, if you don't want to lose your precious 
data, then don't use the same name. But if you truly, really must 
overwrite e, then there is a simple work-around:

e = "my precious data"
try:
    1/0
except Exception as err:
    e = err


Having the exception name unbound at the end of the block is a weird and 
unfortunate wart on the language, but not as unfortunate as having 
exceptions cause long-lasting reference cycles.


-- 
Steve


More information about the Python-Dev mailing list