classification
Title: Reassgining ZeroDivisionError will lead to bug in Except clause
Type: compile error Stage: resolved
Components: Interpreter Core Versions: Python 3.10
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Dennis Sweeney, eric.smith, xxm
Priority: normal Keywords:

Created on 2020-12-14 06:02 by xxm, last changed 2020-12-14 13:35 by eric.smith. This issue is now closed.

Messages (5)
msg382953 - (view) Author: Xinmeng Xia (xxm) Date: 2020-12-14 06:02
Running the following program:
==============================
def foo():
    try:
        1/0
    except ZeroDivisionError as e:
       	ZeroDivisionError = 1
foo()
==============================
The expected output should be nothing. ZeroDivisionError is caught and then reassignment is executed. However, running this program in Python3.10 will lead to the following error: 

Traceback (most recent call last):
  File "/home/xxm/Desktop/nameChanging/error/1.py", line 5, in foo
    1/0
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/xxm/Desktop/nameChanging/error/1.py", line 8, in <module>
    foo()
  File "/home/xxm/Desktop/nameChanging/error/1.py", line 6, in foo
    except Exception as e:
UnboundLocalError: local variable 'Exception' referenced before assignment
msg382954 - (view) Author: Xinmeng Xia (xxm) Date: 2020-12-14 06:17
Similar bugs exist in other exceptions.
msg382967 - (view) Author: Dennis Sweeney (Dennis Sweeney) * (Python triager) Date: 2020-12-14 09:23
This is just how local/nonlocal/global/builtin variables work in Python.

When you assign to a name anywhere inside of a function, all occurrences of that name refer by default to a local variable. So the line "ZeroDivisionError = 1" tells the foo() function that it has some local variable called "ZeroDivisionError". In order to make sure that the ZeroDivisionError always refers to the builtin exception, you need to add a global statement:

>>> def foo():
...     global ZeroDivisionError
...     try:
...         1/0
...     except ZeroDivisionError as e:
...         ZeroDivisionError = 1

>>> foo()
>>> ZeroDivisionError
1


See also: https://docs.python.org/3/faq/programming.html?highlight=global#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value
msg382987 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2020-12-14 13:34
This code is working as expected, so I'm closing this.
msg382988 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2020-12-14 13:35
And thanks, Dennis, for the explanation as to why it's the expected behavior.
History
Date User Action Args
2020-12-14 13:35:22eric.smithsetmessages: + msg382988
2020-12-14 13:34:11eric.smithsetstatus: open -> closed

nosy: + eric.smith
messages: + msg382987

resolution: not a bug
stage: resolved
2020-12-14 09:23:10Dennis Sweeneysetnosy: + Dennis Sweeney
messages: + msg382967
2020-12-14 06:17:25xxmsetmessages: + msg382954
2020-12-14 06:02:52xxmcreate