Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
fixes:
- |
Disabling retries for a synchronous function with an asynchronous sleep
callable now returns the function's result instead of raising TypeError
when the asynchronous wrapper tries to await it.
2 changes: 1 addition & 1 deletion tenacity/asyncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ def wraps(self, fn: t.Callable[P, R]) -> _RetryDecorated[P, R]:
)
async def async_wrapped(*args: t.Any, **kwargs: t.Any) -> t.Any:
if not self.enabled:
return await fn(*args, **kwargs) # type: ignore[misc]
return await _utils.wrap_to_async_func(fn)(*args, **kwargs)
# Always create a copy to prevent overwriting the local contexts when
# calling the same wrapped functions multiple times in the same stack
copy = self.copy()
Expand Down
15 changes: 15 additions & 0 deletions tests/test_asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,21 @@ async def foo() -> None:


class TestSyncFunctionWithAsyncSleep(unittest.TestCase):
@asynctest
async def test_disabled_sync_function_with_async_sleep(self) -> None:
mock_sleep = mock.AsyncMock()
calls = 0

@retry(sleep=mock_sleep, enabled=False, retry=retry_if_result(lambda _: True))
def sync_function() -> Any:
nonlocal calls
calls += 1
return "ok"

assert await sync_function() == "ok"
assert calls == 1
mock_sleep.assert_not_called()

@asynctest
async def test_sync_function_with_async_sleep(self) -> None:
"""A sync function with an async sleep callable uses AsyncRetrying."""
Expand Down
Loading