From cb15300d9b4358d9bdb6cfd33d433368700b3abe Mon Sep 17 00:00:00 2001 From: Richard Si Date: Thu, 14 Mar 2024 06:25:38 -0400 Subject: [PATCH] Lazy import asyncio.sleep as it's expensive (#450) 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. --- tenacity/_asyncio.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tenacity/_asyncio.py b/tenacity/_asyncio.py index 27c2664..b06303f 100644 --- a/tenacity/_asyncio.py +++ b/tenacity/_asyncio.py @@ -18,7 +18,6 @@ import functools import sys import typing as t -from asyncio import sleep from tenacity import AttemptManager from tenacity import BaseRetrying @@ -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