mock_sobes
← Python — Internals
middle correct_vs_wrong #199
Два варианта context manager для timeout-обёртки. Какой защищён от потенциальных ошибок при исключениях?
Вариант 1
import signal

class Timeout:
    def __init__(self, seconds):
        self.seconds = seconds
    def __enter__(self):
        signal.alarm(self.seconds)
    def __exit__(self, *args):
        signal.alarm(0)

with Timeout(5):
    do_something()
Вариант 2
from contextlib import contextmanager
import signal

class TimeoutError(Exception):
    pass

@contextmanager
def timeout(seconds: int):
    def handler(signum, frame):
        raise TimeoutError(f"after {seconds}s")
    old = signal.signal(signal.SIGALRM, handler)
    signal.alarm(seconds)
    try:
        yield
    finally:
        # Восстанавливаем старый handler и снимаем alarm —
        # даже если внутри `with` упало.
        signal.alarm(0)
        signal.signal(signal.SIGALRM, old)

with timeout(5):
    do_something()
Чтобы решить вопрос и сохранить попытку — войди.