What happens to exceptions raised in a with statement expression?

569 views Asked by At

My understanding of Python's with statement is as follows:

with statement = with + expression + as + target + : + suit

  1. expression is executed and returns a context manager
  2. context manager's __enter__ returns a value to target
  3. The suite is executed.
  4. context manager's __exit__ method is invoked

I know exceptions can be handled in step2 and step3, my question is that if an exception is thrown during the step1 when expression is executed, can I get a context manager?

If not does that mean that the with statement just ensures the suit to be executed and close properly?

Like with open("file") as f, if the file does not exist what will happen?

1

There are 1 answers

0
Martijn Pieters On BEST ANSWER

The with statement only manages exceptions in step 3. If an exception is raised in step 1 (executing expression) or in step 2 (executing the context manager __enter__ method), you do not have a (valid and working) context manager to hand the exception to.

So if the file does not exist, an exception is raised in step 1 and cannot be handled by a context manager, because that context manager was never created.

If that is a problem, you can always execute the expression part separately:

try:
    context_manager = expression
except SomeSpecificException:
    # do something about the exception
else:
    with context_manager as target:
        # execute the suite

If the exception is raised in __enter__ (step 2) the context hasn’t yet been entered and so __exit__ will not be called. Your only option to handle an exception at that step is to put the whole with statement inside a try...except block.