2

When running this example func:

from typing import Tuple, Any, Optional

def func() -> Tuple[Any, Optional[Exception]]:
    exc = None
    ret = None
    try:
        # code here, if successful assign result to `ret`
        ret = "Result"
        # comment this line out and the code works
        raise Exception
    except Exception as exc:
        exc.__traceback__ = None
        # Error logging here
        pass
    finally:
        return ret, exc

print(func())  # expected: ("Result", <Exception instance>)

the last line (return ret, exc) raises UnboundLocalError: local variable 'exc' referenced before assignment even tho exc is definitively bound in the first line of the function (exc = None). This can be fixed by changing the except-clause like so:

except Exception as exc1:
    exc = exc1
    exc.__traceback__ = None
    # Error logging here
    pass

Questions:

  1. Is it possible to avoid using another variable (in my example exc1) while still avoiding the UnboundLocalError?
  2. Why does the except <Exception> as <var> statement "swallow" already defined local variables?

1 Answer 1

1

This case is described in 8.4. 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

   try:
       foo
   finally:
       del N

This means the exception must be assigned to a different name to be able to refer to it after the except clause. Exceptions are cleared because with the traceback attached to them, they form a reference cycle with the stack frame, keeping all locals in that frame alive until the next garbage collection occurs.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.