From 732eaa34f782e31e891bbbd4aa524e42b27f3bc7 Mon Sep 17 00:00:00 2001 From: Javier Santacruz Date: Tue, 7 Jun 2022 12:28:57 +0200 Subject: [PATCH] Get max_tries/max_time values for every call fixes #160 --- backoff/_sync.py | 22 ++++++++-------------- tests/test_backoff.py | 23 +++++++++++++++++++++++ tests/test_backoff_async.py | 25 +++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/backoff/_sync.py b/backoff/_sync.py index ecc592d..1c54ecc 100644 --- a/backoff/_sync.py +++ b/backoff/_sync.py @@ -28,11 +28,8 @@ def retry_predicate(target, wait_gen, predicate, @functools.wraps(target) def retry(*args, **kwargs): - - # update variables from outer function args - nonlocal max_tries, max_time - max_tries = _maybe_call(max_tries) - max_time = _maybe_call(max_time) + max_tries_value = _maybe_call(max_tries) + max_time_value = _maybe_call(max_time) tries = 0 start = datetime.datetime.now() @@ -50,9 +47,9 @@ def retry(*args, **kwargs): ret = target(*args, **kwargs) if predicate(ret): - max_tries_exceeded = (tries == max_tries) + max_tries_exceeded = (tries == max_tries_value) max_time_exceeded = (max_time is not None and - elapsed >= max_time) + elapsed >= max_time_value) if max_tries_exceeded or max_time_exceeded: _call_handlers(on_giveup, **details, value=ret) @@ -86,11 +83,8 @@ def retry_exception(target, wait_gen, exception, @functools.wraps(target) def retry(*args, **kwargs): - - # update variables from outer function args - nonlocal max_tries, max_time - max_tries = _maybe_call(max_tries) - max_time = _maybe_call(max_time) + max_tries_value = _maybe_call(max_tries) + max_time_value = _maybe_call(max_time) tries = 0 start = datetime.datetime.now() @@ -109,9 +103,9 @@ def retry(*args, **kwargs): try: ret = target(*args, **kwargs) except exception as e: - max_tries_exceeded = (tries == max_tries) + max_tries_exceeded = (tries == max_tries_value) max_time_exceeded = (max_time is not None and - elapsed >= max_time) + elapsed >= max_time_value) if giveup(e) or max_tries_exceeded or max_time_exceeded: _call_handlers(on_giveup, **details) diff --git a/tests/test_backoff.py b/tests/test_backoff.py index e6b3657..4e70fec 100644 --- a/tests/test_backoff.py +++ b/tests/test_backoff.py @@ -548,6 +548,29 @@ def exceptor(): assert len(log) == 3 +def test_on_exception_callable_max_tries_reads_every_time(monkeypatch): + monkeypatch.setattr('time.sleep', lambda x: None) + + lookups = [] + def lookup_max_tries(): + lookups.append(True) + return 3 + + @backoff.on_exception(backoff.constant, + ValueError, + max_tries=lookup_max_tries) + def exceptor(): + raise ValueError() + + with pytest.raises(ValueError): + exceptor() + + with pytest.raises(ValueError): + exceptor() + + assert len(lookups) == 2 + + def test_on_exception_callable_gen_kwargs(): def lookup_foo(): diff --git a/tests/test_backoff_async.py b/tests/test_backoff_async.py index d8219fd..341a6b8 100644 --- a/tests/test_backoff_async.py +++ b/tests/test_backoff_async.py @@ -571,6 +571,31 @@ async def exceptor(): assert len(log) == 3 +@pytest.mark.asyncio +async def test_on_exception_callable_max_tries_reads_every_time(monkeypatch): + monkeypatch.setattr('asyncio.sleep', _await_none) + + lookups = [] + def lookup_max_tries(): + lookups.append(True) + return 3 + + @backoff.on_exception(backoff.constant, + ValueError, + max_tries=lookup_max_tries) + def exceptor(): + raise ValueError() + + with pytest.raises(ValueError): + exceptor() + + with pytest.raises(ValueError): + exceptor() + + assert len(lookups) == 2 + + + @pytest.mark.asyncio async def test_on_exception_callable_gen_kwargs():