"Retry" из модуля упорства не работает с генератором

У меня проблема с использованием инструмента "Повторить попытку" из библиотеки упорства в python3.Когда я использую генератор, декоратор "retry" не работает.

У меня есть образец кода, иллюстрирующий мою ситуацию:

from tenacity import retry, wait_exponential

@retry(wait=wait_exponential(multiplier=1, min=1, max=1))
def test_retry():
print("test retry from tenacity")
for i in range(10):
    if i == 0: raise Exception
    yield i

def gen():
    yield from test_retry()

bar = gen()
for foo in bar:
    print(foo)

Когда он вызывает исключение, он не повторяет попытку. У кого-нибудь есть идеи, почему это не работает?

Благодарность

1 ответ

Это ошибка / особенность / болото с самой Tenacity, когда логика повтора не работает в функциях генератора. Разработчики Tenacity заявляют, что это происходит потому, что "генераторы внутренне используют исключения".Первоначальный разработчик далее пишет, что "tenacity.retry() обернул функцию генератора, а не сам генератор (то есть код пользователя)".По сути, нет никаких планов по изменению этого поведения.

Чтобы справиться с этим, аннотации Tenacity должны быть добавлены к методам, вызывающим генераторы, где Tenacity может легко перехватывать исключения, когда они всплывают через стек вызовов. Важно: функции генератора также не должны скрывать исключения.

# in generator do this and add retry annotations to calling method
...
try: 
    do_something()
except Exception as ex: 
    log_or_do_something_else()
    raise
finally: 
    cleanup()
yield something
...


# in generator don't do this
...
try: 
    do_something()
except Exception as ex: 
    pass
yield something
...
Другие вопросы по тегам