Python 3 removes name binding from outer scope

Rustom Mody rustompmody at gmail.com
Tue Jul 25 02:47:17 EDT 2017


On Tuesday, July 25, 2017 at 12:04:45 PM UTC+5:30, Ben Finney wrote:
> Ethan Furman writes:
> 
> > Something like:
> >
> >     try:
> >         ....
> >     except ZeroDivisionError as dead_exc:
> >         exc = dead_exc
> >         ....
> >     ....
> >     print(text_template.format(exc=exc)
> 
> That strikes me as busy-work; the name in the ‘except’ clause already
> *has* the object, and is a servicable name already.
> 
> Having to make another name for the same object, merely to avoid some
> surprising behaviour, is IMO un-Pythonic.
> 
> > > How are we meant to reliably preserve the name binding to use it
> > > *after* the ‘except’ clause?
> >
> > Reassign to something else, like my example above.
> >
> > > When did this change come into Python, where is it documented?
> >
> > Documented at:  https://docs.python.org/3/reference/compound_stmts.html#the-try-statement [1]
> >
> > Don't recall exactly when changed.
> 
> The Python 3.0 documentation describes the behaviour::
> 
>     When an exception has been assigned using ‘as target’, it is cleared
>     at the end of the except clause. […]
> 
>     That means that you have to assign the exception to a different name
>     if you want to be able to refer to it after the except clause. The
>     reason for this is that with the traceback attached to them,
>     exceptions will form a reference cycle with the stack frame, keeping
>     all locals in that frame alive until the next garbage collection
>     occurs.
> 
>     <URL:https://docs.python.org/3.0/reference/compound_stmts.html#the-try-statement>
> 
> PEP 3000 documents the change::
> 
>     This PEP intends to resolve this issue [of a reference cycle] by
>     adding a cleanup semantic to ‘except’ clauses in Python 3 whereby
>     the target name is deleted at the end of the ‘except’ suite.
> 
>     <URL:https://www.python.org/dev/peps/pep-3110/>
> 
> So that implies it changed with Python 3.0.
> 
> > > Would I be right to report this as a bug in Python 3?
> >
> > No.
> 
> I do consider it a bug to break that code, from my original message,
> which *explicitly* has the name already bound before the exception
> handling begins.

+1
You can call it bug or bug-promoted-to-feature :D

I call it surprising because I dont know of any other case in python where
a delete is user-detectable
ie python's delete of objects always works quietly behind the scenes whereas
this adds a leakiness to the memory-management abstraction


> 
> But I must concede that, given it's been this way since Python 3.0, it
> is unlikely a bug report now would get it changed.

It could be more prominently documented
> 
> -- 
>  \     “We should strive to do things in [Gandhi's] spirit… not to use |
>   `\   violence in fighting for our cause, but by non-participation in |
> _o__)                       what we believe is evil.” —Albert Einstein |
> Ben Finney

Interesting to see this adjacent to news that non-participation is about 
to be criminalized double of rape [20 years + a million dollars]
http://www.telesurtv.net/english/news/Bipartisan-US-Bill-Moves-to-Criminalize-BDS-Support-20170720-0001.html



More information about the Python-list mailing list