Skip to content

Commit

Permalink
Lazy import asyncio.sleep as it's expensive (#450)
Browse files Browse the repository at this point in the history
On my system, importing tenacity (_without tornado_) takes 35ms, and
asyncio is singlehandedly responsible for 15ms. Some users do not ever
use AsyncRetrying (or asyncio in their project generally) and it would
be a shame for them to incur a unnecessary import penalty.

Full disclaimer: I pursued this change primarily to reduce pip's startup
time where asyncio was a nontrivial portion of the import timeline.
  • Loading branch information
ichard26 authored Mar 14, 2024
1 parent c5d2d8b commit cb15300
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions tenacity/_asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import functools
import sys
import typing as t
from asyncio import sleep

from tenacity import AttemptManager
from tenacity import BaseRetrying
Expand All @@ -31,11 +30,20 @@
WrappedFn = t.TypeVar("WrappedFn", bound=t.Callable[..., t.Awaitable[t.Any]])


def asyncio_sleep(duration: float) -> t.Awaitable[None]:
# Lazy import asyncio as it's expensive (responsible for 25-50% of total import overhead).
import asyncio

return asyncio.sleep(duration)


class AsyncRetrying(BaseRetrying):
sleep: t.Callable[[float], t.Awaitable[t.Any]]

def __init__(
self, sleep: t.Callable[[float], t.Awaitable[t.Any]] = sleep, **kwargs: t.Any
self,
sleep: t.Callable[[float], t.Awaitable[t.Any]] = asyncio_sleep,
**kwargs: t.Any,
) -> None:
super().__init__(**kwargs)
self.sleep = sleep
Expand Down

0 comments on commit cb15300

Please sign in to comment.