"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
...