[Python-Dev] Compilation of "except FooExc as var" adds useless store
On Sun, Jan 06, 2019 at 03:03:03PM +0200, Paul Sokolovsky wrote:
> 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 don't think anyone *likes* the current behaviour. Speaking for myself,
I think it is definitely a wart on the language, but a justifiable one,
since the alternative is worse.
So yes, it is strange, and is something that Python programmers have to
learn. Probably through experience.
> I would
> definitely find a behavior of merely clearing an "except" target
> variable to be more understandable than magic fiddling with namespaces.
I don't understand what this means. What is "clearing an except target"?
Do you mean deleting the target name? Names are either bound to an
object, or they aren't bound at all, so I don't know what it means to
"clear" a name if it doesn't mean delete it.
> > 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?
It isn't an emulation of lexical scope at all. Only the exception target
is deleted, not other variables bound inside the block.
But a better question is, why would you (generic, not you personally)
imagine that, alone out of all flow control statements, ONLY "except"
clauses introduce a new scope? Every other flow control statement (for,
while, if, elif, else, try, with) runs in the current scope. The only
statements which create a new scope are def and class. (Did I miss any?)
> 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.
Wouldn't that mean that MicroPython suffers from the exception/traceback
reference cycle problem? How do you propose to solve that?