Python 3 removes name binding from outer scope

Ben Finney ben+python at benfinney.id.au
Mon Jul 24 21:41:54 EDT 2017


Howdy all,

How can I stop Python from deleting a name binding, when that name is
used for binding the exception that is caught? When did this change in
behaviour come into Python?


I am writing code to run on both Python 2 and Python 3::

    exc = None
    try:
        1/0
        text_template = "All fine!"
    except ZeroDivisionError as exc:
        text_template = "Got exception: {exc.__class__.__name__}"

    print(text_template.format(exc=exc))

Notice that `exc` is explicitly bound before the exception handling, so
Python knows it is a name in the outer scope.


On Python 2.7, this runs fine and the ‘exc’ name survives to be used in
the ‘format’ call::

    Got exception: ZeroDivisionError

Great, this is exactly what I want: The ‘except’ clause binds the name
and I can use that name in the rest of the function to refer to the
exception object.


On Python 3.5, the ‘format’ call fails because apparently the ‘exc’
binding is *deleted*::

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'exc' is not defined

Why is the ‘exc’ binding deleted from the outer scope? How are we meant
to reliably preserve the name binding to use it *after* the ‘except’
clause?

When did this change come into Python, where is it documented?

Would I be right to report this as a bug in Python 3?

-- 
 \           “The cost of education is trivial compared to the cost of |
  `\                                     ignorance.” —Thomas Jefferson |
_o__)                                                                  |
Ben Finney




More information about the Python-list mailing list