[Python-Dev] Compilation of "except FooExc as var" adds useless store
On Sun, 6 Jan 2019 23:10:24 +1100
Steven D'Aprano <steve at pearwood.info> wrote:
> > # 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
Ack. Such an explanation makes sense, though semantics behind it is
"magic". And given that variable deletion happens conditionally on
whether exception happened or not, it's still pretty strange. I would
definitely find a behavior of merely clearing an "except" target
variable to be more understandable than magic fiddling with namespaces.
> The real problem here is that if e holds your precious data, why are
> you assigning an exception to e?
Because I got an idea that "except Exc as var" introduces a nested
lexical scope for "var"? I.e., a completely new variable is introduced,
which may shadow, but not override, any on the enclosing scope.
Why would I get that idea? Well, because lexical scoping is a
well-known concept in many programming languages, Python included. For
example, list/set/etc. comprehensions have proper lexical scope, how
would I imagine that specifically in except clauses, it's not a proper
lexical scoping, but a leaky "emulation" of it?
That said, the description in
doesn't give any false promises regarding lexical scoping. Instead, it
effectively says that the behavior is CPython implementation detail:
"Exceptions are cleared because with the traceback attached to them,
they form a reference cycle"
So, the only thing to take away from this might be indeed an opportunity
to save 4 bytes of bytecode/2 dispatches.
> 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.
Thanks, that summarizes it well. And well, my interest is also how
non-compliant would be for another Python implementation to act
differently, specifically to skip wrapping an except handler body in
try-finally (i.e., go back to Python2 behavior). I'm keen to add such
an option to my fork of MicroPython.
Paul mailto:pmiscml at gmail.com