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

Chris Angelico rosuav at gmail.com
Sun Jan 6 06:19:39 EST 2019


On Sun, Jan 6, 2019 at 10:12 PM Paul Sokolovsky <pmiscml at gmail.com> wrote:
> It's clear that what happens there is that first None is stored to N,
> just to del it as the next step. Indeed, that's what done in the
> compile.c:
>
> https://github.com/python/cpython/blob/master/Python/compile.c#L2905
>
> Storing None looks superfluous.
>
> There's no clear explanation why it's done like that, so probably an
> artifact of the initial implementation.

With something as clearly deliberate as this, it's generally safe to
assume there's a good reason for it. But I would very much like to see
that reason documented, preferably with an example of something that
could otherwise fail.

> 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)
> ----
>
> So, perhaps the change should be not removing "e = None" part, but
> conversely, removing the "del e" part.

No, there's a good reason for having the "del e", and that's to
prevent reference loops (since the exception includes the full
traceback, including all local variables). However, I would argue -
and HAVE argued - that this would be a perfect situation for an inner
scope, where the inner variable "e" is actually shadowing, rather than
overwriting, your outer "e". But the push-back against *that* proposal
was insane.

ChrisA


More information about the Python-Dev mailing list