This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: "as" variable in except block deletes local variables with same name
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: alanr, eric.smith, remi.lapeyre
Priority: normal Keywords:

Created on 2020-03-03 20:59 by alanr, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
foo.py alanr, 2020-03-03 20:59 Program which illustrates the surprising behavior...
Messages (4)
msg363300 - (view) Author: Alan Robertson (alanr) Date: 2020-03-03 20:59
When an exception "as" variable occurs, it deletes local variables with the same name. This is certainly surprising, and doesn't appear to be a documented behavior (but maybe I don't know where to look). The word "bug" comes to mind.  The following few lines of code illustrate it nicely:

def testme():
    err = Exception("nothing worked")
    try:
        raise ValueError("no value")
    except ValueError as err:
        pass
    print(err)

testme()
msg363302 - (view) Author: Rémi Lapeyre (remi.lapeyre) * Date: 2020-03-03 21:24
Hi Alan, this is documented at https://docs.python.org/3/reference/compound_stmts.html#the-try-statement:


> When an exception has been assigned using as target, it is cleared at the end of the except clause. This is as if
>
> except E as N:
>    foo
>
> was translated to
>
> except E as N:
>    try:
>        foo
>    finally:
>        del N
>

This is because the exception keeps a reference to the code frame that would make a cycle with the locals which would not be destroyed until the next garbage collection.

I think you will need to use a different name in the except clause.
msg363303 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2020-03-03 21:27
Yes, this is a known issue.

See https://docs.python.org/3/reference/compound_stmts.html#the-try-statement, in particular the sentence "When an exception has been assigned using as target, it is cleared at the end of the except clause" and the following text.

Basically, at the end of the exception block python does a "del err" in order to prevent a long-lived reference cycle including the exception.
msg363309 - (view) Author: Alan Robertson (alanr) Date: 2020-03-03 22:20
Thanks for your kind explanation. I may even vaguely remember seeing this sometime in the past. Thanks much for your time!
History
Date User Action Args
2022-04-11 14:59:27adminsetgithub: 84022
2020-03-03 22:20:29alanrsetmessages: + msg363309
2020-03-03 21:27:49eric.smithsetstatus: open -> closed

type: behavior

nosy: + eric.smith
messages: + msg363303
resolution: not a bug
stage: resolved
2020-03-03 21:24:05remi.lapeyresetnosy: + remi.lapeyre
messages: + msg363302
2020-03-03 20:59:02alanrcreate