<div dir="ltr"><div><div><div><div><div><div>Thank you for the responses. I did not realize that the delete fast was added because the traceback is on the exception, that makes a lot of sense. Regarding the case of:<br><br></div>try:<br></div>    import a<br></div>except ImportError:<br></div>    import b as a<br><br><br></div>my proposal would still have this work as intended because the first import would appear as an assignment to the name `a` outside the scope of the handler which would case the inner scope to emit a store deref after the import instead of a store fast. The only thing this change would block is introducing a new variable which is only defined inside the except handler.<br><br></div><div>> So if you still want to champion your proposal, it's not enough to<br>
> demonstrate that it could be done. You're going to have to demonstrate<br>
> not only a benefit from the change, but that the benefit is worth<br>
> breaking other people's code.<br><br></div><div>To be honest, this was mainly proposed because I thought about _how_ to implement it and less about _should_ we implement this. I implemented a small version of this to generate the dis outputs that I put in the first email. After reading the responses I agree that this should probably not be added; I do not think that we need to discuss this further unless someone else has strong feelings about this.<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Apr 9, 2016 at 3:44 AM, Steven D'Aprano <span dir="ltr"><<a href="mailto:steve@pearwood.info" target="_blank">steve@pearwood.info</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Fri, Apr 08, 2016 at 05:03:05PM -0400, Joseph Jevnik wrote:<br>
<br>
> I would like to propose a change to exception handlers to make it harder to<br>
> accidently leak names defined only in the exception handler blocks. This<br>
> change follows from the decision to delete the name of an exception at the<br>
> end of a handler. The goal of this change is to prevent people from relying<br>
> on names that are defined only in a handler.<br>
<br>
</span>An interesting proposal, but you're missing one critical point: why is<br>
it harmful to create names inside an except block?<br>
<br>
There is a concrete reason why Python 3, and not Python 2, deletes the<br>
"except Exception as err" name when the except block leaves: because<br>
exceptions now hold on to a lot more call info, which can prevent<br>
objects from being garbage-collected. But the same doesn't apply to<br>
arbitrary names.<br>
<br>
At the moment, only a few block statements create a new scope: def and<br>
class mostly. In particular, no flow control statement does: if, elif,<br>
else, for, while, try, except all use the existing scope. This is a nice<br>
clean design, and in my opinion must better than the rule that any<br>
indented block is a new scope. I would certainly object to making<br>
"except" the only exception (pun intended) and I would object even more<br>
to making *all* the block statements create a new scope.<br>
<br>
Here is an example of how your proposal would bite people. Nearly all by<br>
code is hybrid 2+3 code, so I often have a construct like this at the<br>
start of modules:<br>
<br>
try:<br>
    import builtins  # Python 3.x<br>
except ImportError:<br>
    # Python 2.x<br>
    import __builtin__ as builtins<br>
<br>
<br>
Nice and clean. But what if try and except introduced a new scope? I<br>
would have to write:<br>
<br>
builtins = None<br>
try:<br>
    global builtins<br>
    import builtins<br>
except ImportError:<br>
    global builtins<br>
    import __builtin__ as builtins<br>
assert builtins is not None<br>
<br>
<br>
Since try and except are different scopes, I need a separate global<br>
declaration in each. If you think this second version is an improvement<br>
over the first, then our ideas of what makes good looking code are so<br>
far apart that I don't think its worth discussing this further :-)<br>
<br>
If only except is a different scope, then I have this shorter version:<br>
<br>
try:  # global scope<br>
    import builtins<br>
except ImportError:  # local scope<br>
    global builtins<br>
    import __builtin__ as builtins<br>
<span class=""><br>
<br>
<br>
> As an example, let's looks at a function with a try except:<br>
><br>
><br>
> def f():<br>
>     try:<br>
>         ...<br>
>     except:<br>
>         a = 1<br>
>     return a<br>
><br>
><br>
> This function will only work if the body raises some exception, otherwise<br>
> we will get an UnBoundLocalError.<br>
<br>
</span>Not necessary. It depends on what is hidden by the ... dots. For<br>
example:<br>
<br>
def f():<br>
    try:<br>
        a = sequence.pop()<br>
    except AttributeError:<br>
        a = -1<br>
    return a<br>
<br>
<br>
It might not be the most Pythonic code around, but it works, and your<br>
proposal will break it.<br>
<br>
Bottom line is, there's nothing fundamentally wrong with except blocks<br>
*not* starting a new scope. I'm not sure if there's any real benefit to<br>
the proposal, but even if there is, I doubt it's worth the cost of<br>
breaking existing working code.<br>
<br>
So if you still want to champion your proposal, it's not enough to<br>
demonstrate that it could be done. You're going to have to demonstrate<br>
not only a benefit from the change, but that the benefit is worth<br>
breaking other people's code.<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
<br>
--<br>
Steve<br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</div></div></blockquote></div><br></div>