Могу ли я вызвать исключение в `__exit__`? - PullRequest
0 голосов
/ 30 марта 2020

Могу ли я вызвать исключения в методе __exit__? Если это так, будет ли распространяться это исключение из блока with?

Пример:

class X:
    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        raise MyException()


with X() as x:
    pass

// What happens here? Is `MyException` propagated up the stack?

1 Ответ

1 голос
/ 30 марта 2020

Исключения, возникающие во время выполнения этого метода, заменят все исключения, возникшие в теле оператора with.

https://docs.python.org/3/library/stdtypes.html#contextmanager. exit

И мы могли бы увидеть с заявлением для более подробной информации. Независимо от того, выбрасывает ли SUITE исключение или нет, исключение, вызванное __exit__, всегда выбрасывается вызывающей стороне.

with EXPRESSION as TARGET:
    SUITE

семантически эквивалентно:

manager = (EXPRESSION)
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager)
hit_except = False

try:
    TARGET = value
    SUITE
except:
    hit_except = True
    if not exit(manager, *sys.exc_info()):
        raise
finally:
    if not hit_except:
        exit(manager, None, None, None)
...