Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
__init__.py211 linesDownload Raw Back to asyncio
1# Copyright 2016 Étienne Bersac2# Copyright 2016 Julien Danjou3# Copyright 2016 Joshua Harlow4# Copyright 2013-2014 Ray Holder5#6# Licensed under the Apache License, Version 2.0 (the "License");7# you may not use this file except in compliance with the License.8# You may obtain a copy of the License at9#10# http://www.apache.org/licenses/LICENSE-2.011#12# Unless required by applicable law or agreed to in writing, software13# distributed under the License is distributed on an "AS IS" BASIS,14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.15# See the License for the specific language governing permissions and16# limitations under the License.17 18import functools19import sys20import typing as t21 22import tenacity23from tenacity import AttemptManager24from tenacity import BaseRetrying25from tenacity import DoAttempt26from tenacity import DoSleep27from tenacity import RetryCallState28from tenacity import RetryError29from tenacity import after_nothing30from tenacity import before_nothing31from tenacity import _utils32 33# Import all built-in retry strategies for easier usage.34from .retry import RetryBaseT35from .retry import retry_all  # noqa36from .retry import retry_any  # noqa37from .retry import retry_if_exception  # noqa38from .retry import retry_if_result  # noqa39from ..retry import RetryBaseT as SyncRetryBaseT40 41if t.TYPE_CHECKING:42    from tenacity.stop import StopBaseT43    from tenacity.wait import WaitBaseT44 45WrappedFnReturnT = t.TypeVar("WrappedFnReturnT")46WrappedFn = t.TypeVar("WrappedFn", bound=t.Callable[..., t.Awaitable[t.Any]])47 48 49def _portable_async_sleep(seconds: float) -> t.Awaitable[None]:50    # If trio is already imported, then importing it is cheap.51    # If trio isn't already imported, then it's definitely not running, so we52    # can skip further checks.53    if "trio" in sys.modules:54        # If trio is available, then sniffio is too55        import trio56        import sniffio57 58        if sniffio.current_async_library() == "trio":59            return trio.sleep(seconds)60    # Otherwise, assume asyncio61    # Lazy import asyncio as it's expensive (responsible for 25-50% of total import overhead).62    import asyncio63 64    return asyncio.sleep(seconds)65 66 67class AsyncRetrying(BaseRetrying):68    def __init__(69        self,70        sleep: t.Callable[71            [t.Union[int, float]], t.Union[None, t.Awaitable[None]]72        ] = _portable_async_sleep,73        stop: "StopBaseT" = tenacity.stop.stop_never,74        wait: "WaitBaseT" = tenacity.wait.wait_none(),75        retry: "t.Union[SyncRetryBaseT, RetryBaseT]" = tenacity.retry_if_exception_type(),76        before: t.Callable[77            ["RetryCallState"], t.Union[None, t.Awaitable[None]]78        ] = before_nothing,79        after: t.Callable[80            ["RetryCallState"], t.Union[None, t.Awaitable[None]]81        ] = after_nothing,82        before_sleep: t.Optional[83            t.Callable[["RetryCallState"], t.Union[None, t.Awaitable[None]]]84        ] = None,85        reraise: bool = False,86        retry_error_cls: t.Type["RetryError"] = RetryError,87        retry_error_callback: t.Optional[88            t.Callable[["RetryCallState"], t.Union[t.Any, t.Awaitable[t.Any]]]89        ] = None,90    ) -> None:91        super().__init__(92            sleep=sleep,  # type: ignore[arg-type]93            stop=stop,94            wait=wait,95            retry=retry,  # type: ignore[arg-type]96            before=before,  # type: ignore[arg-type]97            after=after,  # type: ignore[arg-type]98            before_sleep=before_sleep,  # type: ignore[arg-type]99            reraise=reraise,100            retry_error_cls=retry_error_cls,101            retry_error_callback=retry_error_callback,102        )103 104    async def __call__(  # type: ignore[override]105        self, fn: WrappedFn, *args: t.Any, **kwargs: t.Any106    ) -> WrappedFnReturnT:107        self.begin()108 109        retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs)110        is_async = _utils.is_coroutine_callable(fn)111        while True:112            do = await self.iter(retry_state=retry_state)113            if isinstance(do, DoAttempt):114                try:115                    if is_async:116                        result = await fn(*args, **kwargs)117                    else:118                        result = fn(*args, **kwargs)119                except BaseException:  # noqa: B902120                    retry_state.set_exception(sys.exc_info())  # type: ignore[arg-type]121                else:122                    retry_state.set_result(result)123            elif isinstance(do, DoSleep):124                retry_state.prepare_for_next_attempt()125                await self.sleep(do)  # type: ignore[misc]126            else:127                return do  # type: ignore[no-any-return]128 129    def _add_action_func(self, fn: t.Callable[..., t.Any]) -> None:130        self.iter_state.actions.append(_utils.wrap_to_async_func(fn))131 132    async def _run_retry(self, retry_state: "RetryCallState") -> None:  # type: ignore[override]133        self.iter_state.retry_run_result = await _utils.wrap_to_async_func(self.retry)(134            retry_state135        )136 137    async def _run_wait(self, retry_state: "RetryCallState") -> None:  # type: ignore[override]138        if self.wait:139            sleep = await _utils.wrap_to_async_func(self.wait)(retry_state)140        else:141            sleep = 0.0142 143        retry_state.upcoming_sleep = sleep144 145    async def _run_stop(self, retry_state: "RetryCallState") -> None:  # type: ignore[override]146        self.statistics["delay_since_first_attempt"] = retry_state.seconds_since_start147        self.iter_state.stop_run_result = await _utils.wrap_to_async_func(self.stop)(148            retry_state149        )150 151    async def iter(152        self, retry_state: "RetryCallState"153    ) -> t.Union[DoAttempt, DoSleep, t.Any]:  # noqa: A003154        self._begin_iter(retry_state)155        result = None156        for action in self.iter_state.actions:157            result = await action(retry_state)158        return result159 160    def __iter__(self) -> t.Generator[AttemptManager, None, None]:161        raise TypeError("AsyncRetrying object is not iterable")162 163    def __aiter__(self) -> "AsyncRetrying":164        self.begin()165        self._retry_state = RetryCallState(self, fn=None, args=(), kwargs={})166        return self167 168    async def __anext__(self) -> AttemptManager:169        while True:170            do = await self.iter(retry_state=self._retry_state)171            if do is None:172                raise StopAsyncIteration173            elif isinstance(do, DoAttempt):174                return AttemptManager(retry_state=self._retry_state)175            elif isinstance(do, DoSleep):176                self._retry_state.prepare_for_next_attempt()177                await self.sleep(do)  # type: ignore[misc]178            else:179                raise StopAsyncIteration180 181    def wraps(self, fn: WrappedFn) -> WrappedFn:182        wrapped = super().wraps(fn)183        # Ensure wrapper is recognized as a coroutine function.184 185        @functools.wraps(186            fn, functools.WRAPPER_ASSIGNMENTS + ("__defaults__", "__kwdefaults__")187        )188        async def async_wrapped(*args: t.Any, **kwargs: t.Any) -> t.Any:189            # Always create a copy to prevent overwriting the local contexts when190            # calling the same wrapped functions multiple times in the same stack191            copy = self.copy()192            async_wrapped.statistics = copy.statistics  # type: ignore[attr-defined]193            return await copy(fn, *args, **kwargs)194 195        # Preserve attributes196        async_wrapped.retry = self  # type: ignore[attr-defined]197        async_wrapped.retry_with = wrapped.retry_with  # type: ignore[attr-defined]198        async_wrapped.statistics = {}  # type: ignore[attr-defined]199 200        return async_wrapped  # type: ignore[return-value]201 202 203__all__ = [204    "retry_all",205    "retry_any",206    "retry_if_exception",207    "retry_if_result",208    "WrappedFn",209    "AsyncRetrying",210]211 
codekingpro/portable-devtools · Team Ai