first commit
This commit is contained in:
608
venv/Lib/site-packages/pip/_vendor/tenacity/__init__.py
Normal file
608
venv/Lib/site-packages/pip/_vendor/tenacity/__init__.py
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
94
venv/Lib/site-packages/pip/_vendor/tenacity/_asyncio.py
Normal file
94
venv/Lib/site-packages/pip/_vendor/tenacity/_asyncio.py
Normal file
@@ -0,0 +1,94 @@
|
||||
# Copyright 2016 Étienne Bersac
|
||||
# Copyright 2016 Julien Danjou
|
||||
# Copyright 2016 Joshua Harlow
|
||||
# Copyright 2013-2014 Ray Holder
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import functools
|
||||
import sys
|
||||
import typing as t
|
||||
from asyncio import sleep
|
||||
|
||||
from pip._vendor.tenacity import AttemptManager
|
||||
from pip._vendor.tenacity import BaseRetrying
|
||||
from pip._vendor.tenacity import DoAttempt
|
||||
from pip._vendor.tenacity import DoSleep
|
||||
from pip._vendor.tenacity import RetryCallState
|
||||
|
||||
WrappedFnReturnT = t.TypeVar("WrappedFnReturnT")
|
||||
WrappedFn = t.TypeVar("WrappedFn", bound=t.Callable[..., t.Awaitable[t.Any]])
|
||||
|
||||
|
||||
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) -> None:
|
||||
super().__init__(**kwargs)
|
||||
self.sleep = sleep
|
||||
|
||||
async def __call__( # type: ignore[override]
|
||||
self, fn: WrappedFn, *args: t.Any, **kwargs: t.Any
|
||||
) -> WrappedFnReturnT:
|
||||
self.begin()
|
||||
|
||||
retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs)
|
||||
while True:
|
||||
do = self.iter(retry_state=retry_state)
|
||||
if isinstance(do, DoAttempt):
|
||||
try:
|
||||
result = await fn(*args, **kwargs)
|
||||
except BaseException: # noqa: B902
|
||||
retry_state.set_exception(sys.exc_info()) # type: ignore[arg-type]
|
||||
else:
|
||||
retry_state.set_result(result)
|
||||
elif isinstance(do, DoSleep):
|
||||
retry_state.prepare_for_next_attempt()
|
||||
await self.sleep(do)
|
||||
else:
|
||||
return do # type: ignore[no-any-return]
|
||||
|
||||
def __iter__(self) -> t.Generator[AttemptManager, None, None]:
|
||||
raise TypeError("AsyncRetrying object is not iterable")
|
||||
|
||||
def __aiter__(self) -> "AsyncRetrying":
|
||||
self.begin()
|
||||
self._retry_state = RetryCallState(self, fn=None, args=(), kwargs={})
|
||||
return self
|
||||
|
||||
async def __anext__(self) -> AttemptManager:
|
||||
while True:
|
||||
do = self.iter(retry_state=self._retry_state)
|
||||
if do is None:
|
||||
raise StopAsyncIteration
|
||||
elif isinstance(do, DoAttempt):
|
||||
return AttemptManager(retry_state=self._retry_state)
|
||||
elif isinstance(do, DoSleep):
|
||||
self._retry_state.prepare_for_next_attempt()
|
||||
await self.sleep(do)
|
||||
else:
|
||||
raise StopAsyncIteration
|
||||
|
||||
def wraps(self, fn: WrappedFn) -> WrappedFn:
|
||||
fn = super().wraps(fn)
|
||||
# Ensure wrapper is recognized as a coroutine function.
|
||||
|
||||
@functools.wraps(fn)
|
||||
async def async_wrapped(*args: t.Any, **kwargs: t.Any) -> t.Any:
|
||||
return await fn(*args, **kwargs)
|
||||
|
||||
# Preserve attributes
|
||||
async_wrapped.retry = fn.retry # type: ignore[attr-defined]
|
||||
async_wrapped.retry_with = fn.retry_with # type: ignore[attr-defined]
|
||||
|
||||
return async_wrapped # type: ignore[return-value]
|
76
venv/Lib/site-packages/pip/_vendor/tenacity/_utils.py
Normal file
76
venv/Lib/site-packages/pip/_vendor/tenacity/_utils.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# Copyright 2016 Julien Danjou
|
||||
# Copyright 2016 Joshua Harlow
|
||||
# Copyright 2013-2014 Ray Holder
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import sys
|
||||
import typing
|
||||
from datetime import timedelta
|
||||
|
||||
|
||||
# sys.maxsize:
|
||||
# An integer giving the maximum value a variable of type Py_ssize_t can take.
|
||||
MAX_WAIT = sys.maxsize / 2
|
||||
|
||||
|
||||
def find_ordinal(pos_num: int) -> str:
|
||||
# See: https://en.wikipedia.org/wiki/English_numerals#Ordinal_numbers
|
||||
if pos_num == 0:
|
||||
return "th"
|
||||
elif pos_num == 1:
|
||||
return "st"
|
||||
elif pos_num == 2:
|
||||
return "nd"
|
||||
elif pos_num == 3:
|
||||
return "rd"
|
||||
elif 4 <= pos_num <= 20:
|
||||
return "th"
|
||||
else:
|
||||
return find_ordinal(pos_num % 10)
|
||||
|
||||
|
||||
def to_ordinal(pos_num: int) -> str:
|
||||
return f"{pos_num}{find_ordinal(pos_num)}"
|
||||
|
||||
|
||||
def get_callback_name(cb: typing.Callable[..., typing.Any]) -> str:
|
||||
"""Get a callback fully-qualified name.
|
||||
|
||||
If no name can be produced ``repr(cb)`` is called and returned.
|
||||
"""
|
||||
segments = []
|
||||
try:
|
||||
segments.append(cb.__qualname__)
|
||||
except AttributeError:
|
||||
try:
|
||||
segments.append(cb.__name__)
|
||||
except AttributeError:
|
||||
pass
|
||||
if not segments:
|
||||
return repr(cb)
|
||||
else:
|
||||
try:
|
||||
# When running under sphinx it appears this can be none?
|
||||
if cb.__module__:
|
||||
segments.insert(0, cb.__module__)
|
||||
except AttributeError:
|
||||
pass
|
||||
return ".".join(segments)
|
||||
|
||||
|
||||
time_unit_type = typing.Union[int, float, timedelta]
|
||||
|
||||
|
||||
def to_seconds(time_unit: time_unit_type) -> float:
|
||||
return float(time_unit.total_seconds() if isinstance(time_unit, timedelta) else time_unit)
|
51
venv/Lib/site-packages/pip/_vendor/tenacity/after.py
Normal file
51
venv/Lib/site-packages/pip/_vendor/tenacity/after.py
Normal file
@@ -0,0 +1,51 @@
|
||||
# Copyright 2016 Julien Danjou
|
||||
# Copyright 2016 Joshua Harlow
|
||||
# Copyright 2013-2014 Ray Holder
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import typing
|
||||
|
||||
from pip._vendor.tenacity import _utils
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
import logging
|
||||
|
||||
from pip._vendor.tenacity import RetryCallState
|
||||
|
||||
|
||||
def after_nothing(retry_state: "RetryCallState") -> None:
|
||||
"""After call strategy that does nothing."""
|
||||
|
||||
|
||||
def after_log(
|
||||
logger: "logging.Logger",
|
||||
log_level: int,
|
||||
sec_format: str = "%0.3f",
|
||||
) -> typing.Callable[["RetryCallState"], None]:
|
||||
"""After call strategy that logs to some logger the finished attempt."""
|
||||
|
||||
def log_it(retry_state: "RetryCallState") -> None:
|
||||
if retry_state.fn is None:
|
||||
# NOTE(sileht): can't really happen, but we must please mypy
|
||||
fn_name = "<unknown>"
|
||||
else:
|
||||
fn_name = _utils.get_callback_name(retry_state.fn)
|
||||
logger.log(
|
||||
log_level,
|
||||
f"Finished call to '{fn_name}' "
|
||||
f"after {sec_format % retry_state.seconds_since_start}(s), "
|
||||
f"this was the {_utils.to_ordinal(retry_state.attempt_number)} time calling it.",
|
||||
)
|
||||
|
||||
return log_it
|
46
venv/Lib/site-packages/pip/_vendor/tenacity/before.py
Normal file
46
venv/Lib/site-packages/pip/_vendor/tenacity/before.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# Copyright 2016 Julien Danjou
|
||||
# Copyright 2016 Joshua Harlow
|
||||
# Copyright 2013-2014 Ray Holder
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import typing
|
||||
|
||||
from pip._vendor.tenacity import _utils
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
import logging
|
||||
|
||||
from pip._vendor.tenacity import RetryCallState
|
||||
|
||||
|
||||
def before_nothing(retry_state: "RetryCallState") -> None:
|
||||
"""Before call strategy that does nothing."""
|
||||
|
||||
|
||||
def before_log(logger: "logging.Logger", log_level: int) -> typing.Callable[["RetryCallState"], None]:
|
||||
"""Before call strategy that logs to some logger the attempt."""
|
||||
|
||||
def log_it(retry_state: "RetryCallState") -> None:
|
||||
if retry_state.fn is None:
|
||||
# NOTE(sileht): can't really happen, but we must please mypy
|
||||
fn_name = "<unknown>"
|
||||
else:
|
||||
fn_name = _utils.get_callback_name(retry_state.fn)
|
||||
logger.log(
|
||||
log_level,
|
||||
f"Starting call to '{fn_name}', "
|
||||
f"this is the {_utils.to_ordinal(retry_state.attempt_number)} time calling it.",
|
||||
)
|
||||
|
||||
return log_it
|
71
venv/Lib/site-packages/pip/_vendor/tenacity/before_sleep.py
Normal file
71
venv/Lib/site-packages/pip/_vendor/tenacity/before_sleep.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# Copyright 2016 Julien Danjou
|
||||
# Copyright 2016 Joshua Harlow
|
||||
# Copyright 2013-2014 Ray Holder
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import typing
|
||||
|
||||
from pip._vendor.tenacity import _utils
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
import logging
|
||||
|
||||
from pip._vendor.tenacity import RetryCallState
|
||||
|
||||
|
||||
def before_sleep_nothing(retry_state: "RetryCallState") -> None:
|
||||
"""Before call strategy that does nothing."""
|
||||
|
||||
|
||||
def before_sleep_log(
|
||||
logger: "logging.Logger",
|
||||
log_level: int,
|
||||
exc_info: bool = False,
|
||||
) -> typing.Callable[["RetryCallState"], None]:
|
||||
"""Before call strategy that logs to some logger the attempt."""
|
||||
|
||||
def log_it(retry_state: "RetryCallState") -> None:
|
||||
local_exc_info: BaseException | bool | None
|
||||
|
||||
if retry_state.outcome is None:
|
||||
raise RuntimeError("log_it() called before outcome was set")
|
||||
|
||||
if retry_state.next_action is None:
|
||||
raise RuntimeError("log_it() called before next_action was set")
|
||||
|
||||
if retry_state.outcome.failed:
|
||||
ex = retry_state.outcome.exception()
|
||||
verb, value = "raised", f"{ex.__class__.__name__}: {ex}"
|
||||
|
||||
if exc_info:
|
||||
local_exc_info = retry_state.outcome.exception()
|
||||
else:
|
||||
local_exc_info = False
|
||||
else:
|
||||
verb, value = "returned", retry_state.outcome.result()
|
||||
local_exc_info = False # exc_info does not apply when no exception
|
||||
|
||||
if retry_state.fn is None:
|
||||
# NOTE(sileht): can't really happen, but we must please mypy
|
||||
fn_name = "<unknown>"
|
||||
else:
|
||||
fn_name = _utils.get_callback_name(retry_state.fn)
|
||||
|
||||
logger.log(
|
||||
log_level,
|
||||
f"Retrying {fn_name} " f"in {retry_state.next_action.sleep} seconds as it {verb} {value}.",
|
||||
exc_info=local_exc_info,
|
||||
)
|
||||
|
||||
return log_it
|
43
venv/Lib/site-packages/pip/_vendor/tenacity/nap.py
Normal file
43
venv/Lib/site-packages/pip/_vendor/tenacity/nap.py
Normal file
@@ -0,0 +1,43 @@
|
||||
# Copyright 2016 Étienne Bersac
|
||||
# Copyright 2016 Julien Danjou
|
||||
# Copyright 2016 Joshua Harlow
|
||||
# Copyright 2013-2014 Ray Holder
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import time
|
||||
import typing
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
import threading
|
||||
|
||||
|
||||
def sleep(seconds: float) -> None:
|
||||
"""
|
||||
Sleep strategy that delays execution for a given number of seconds.
|
||||
|
||||
This is the default strategy, and may be mocked out for unit testing.
|
||||
"""
|
||||
time.sleep(seconds)
|
||||
|
||||
|
||||
class sleep_using_event:
|
||||
"""Sleep strategy that waits on an event to be set."""
|
||||
|
||||
def __init__(self, event: "threading.Event") -> None:
|
||||
self.event = event
|
||||
|
||||
def __call__(self, timeout: typing.Optional[float]) -> None:
|
||||
# NOTE(harlowja): this may *not* actually wait for timeout
|
||||
# seconds if the event is set (ie this may eject out early).
|
||||
self.event.wait(timeout=timeout)
|
272
venv/Lib/site-packages/pip/_vendor/tenacity/retry.py
Normal file
272
venv/Lib/site-packages/pip/_vendor/tenacity/retry.py
Normal file
@@ -0,0 +1,272 @@
|
||||
# Copyright 2016–2021 Julien Danjou
|
||||
# Copyright 2016 Joshua Harlow
|
||||
# Copyright 2013-2014 Ray Holder
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import abc
|
||||
import re
|
||||
import typing
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from pip._vendor.tenacity import RetryCallState
|
||||
|
||||
|
||||
class retry_base(abc.ABC):
|
||||
"""Abstract base class for retry strategies."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
pass
|
||||
|
||||
def __and__(self, other: "retry_base") -> "retry_all":
|
||||
return retry_all(self, other)
|
||||
|
||||
def __or__(self, other: "retry_base") -> "retry_any":
|
||||
return retry_any(self, other)
|
||||
|
||||
|
||||
RetryBaseT = typing.Union[retry_base, typing.Callable[["RetryCallState"], bool]]
|
||||
|
||||
|
||||
class _retry_never(retry_base):
|
||||
"""Retry strategy that never rejects any result."""
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
return False
|
||||
|
||||
|
||||
retry_never = _retry_never()
|
||||
|
||||
|
||||
class _retry_always(retry_base):
|
||||
"""Retry strategy that always rejects any result."""
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
return True
|
||||
|
||||
|
||||
retry_always = _retry_always()
|
||||
|
||||
|
||||
class retry_if_exception(retry_base):
|
||||
"""Retry strategy that retries if an exception verifies a predicate."""
|
||||
|
||||
def __init__(self, predicate: typing.Callable[[BaseException], bool]) -> None:
|
||||
self.predicate = predicate
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
if retry_state.outcome is None:
|
||||
raise RuntimeError("__call__() called before outcome was set")
|
||||
|
||||
if retry_state.outcome.failed:
|
||||
exception = retry_state.outcome.exception()
|
||||
if exception is None:
|
||||
raise RuntimeError("outcome failed but the exception is None")
|
||||
return self.predicate(exception)
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class retry_if_exception_type(retry_if_exception):
|
||||
"""Retries if an exception has been raised of one or more types."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
exception_types: typing.Union[
|
||||
typing.Type[BaseException],
|
||||
typing.Tuple[typing.Type[BaseException], ...],
|
||||
] = Exception,
|
||||
) -> None:
|
||||
self.exception_types = exception_types
|
||||
super().__init__(lambda e: isinstance(e, exception_types))
|
||||
|
||||
|
||||
class retry_if_not_exception_type(retry_if_exception):
|
||||
"""Retries except an exception has been raised of one or more types."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
exception_types: typing.Union[
|
||||
typing.Type[BaseException],
|
||||
typing.Tuple[typing.Type[BaseException], ...],
|
||||
] = Exception,
|
||||
) -> None:
|
||||
self.exception_types = exception_types
|
||||
super().__init__(lambda e: not isinstance(e, exception_types))
|
||||
|
||||
|
||||
class retry_unless_exception_type(retry_if_exception):
|
||||
"""Retries until an exception is raised of one or more types."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
exception_types: typing.Union[
|
||||
typing.Type[BaseException],
|
||||
typing.Tuple[typing.Type[BaseException], ...],
|
||||
] = Exception,
|
||||
) -> None:
|
||||
self.exception_types = exception_types
|
||||
super().__init__(lambda e: not isinstance(e, exception_types))
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
if retry_state.outcome is None:
|
||||
raise RuntimeError("__call__() called before outcome was set")
|
||||
|
||||
# always retry if no exception was raised
|
||||
if not retry_state.outcome.failed:
|
||||
return True
|
||||
|
||||
exception = retry_state.outcome.exception()
|
||||
if exception is None:
|
||||
raise RuntimeError("outcome failed but the exception is None")
|
||||
return self.predicate(exception)
|
||||
|
||||
|
||||
class retry_if_exception_cause_type(retry_base):
|
||||
"""Retries if any of the causes of the raised exception is of one or more types.
|
||||
|
||||
The check on the type of the cause of the exception is done recursively (until finding
|
||||
an exception in the chain that has no `__cause__`)
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
exception_types: typing.Union[
|
||||
typing.Type[BaseException],
|
||||
typing.Tuple[typing.Type[BaseException], ...],
|
||||
] = Exception,
|
||||
) -> None:
|
||||
self.exception_cause_types = exception_types
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
if retry_state.outcome is None:
|
||||
raise RuntimeError("__call__ called before outcome was set")
|
||||
|
||||
if retry_state.outcome.failed:
|
||||
exc = retry_state.outcome.exception()
|
||||
while exc is not None:
|
||||
if isinstance(exc.__cause__, self.exception_cause_types):
|
||||
return True
|
||||
exc = exc.__cause__
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class retry_if_result(retry_base):
|
||||
"""Retries if the result verifies a predicate."""
|
||||
|
||||
def __init__(self, predicate: typing.Callable[[typing.Any], bool]) -> None:
|
||||
self.predicate = predicate
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
if retry_state.outcome is None:
|
||||
raise RuntimeError("__call__() called before outcome was set")
|
||||
|
||||
if not retry_state.outcome.failed:
|
||||
return self.predicate(retry_state.outcome.result())
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class retry_if_not_result(retry_base):
|
||||
"""Retries if the result refutes a predicate."""
|
||||
|
||||
def __init__(self, predicate: typing.Callable[[typing.Any], bool]) -> None:
|
||||
self.predicate = predicate
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
if retry_state.outcome is None:
|
||||
raise RuntimeError("__call__() called before outcome was set")
|
||||
|
||||
if not retry_state.outcome.failed:
|
||||
return not self.predicate(retry_state.outcome.result())
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class retry_if_exception_message(retry_if_exception):
|
||||
"""Retries if an exception message equals or matches."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message: typing.Optional[str] = None,
|
||||
match: typing.Optional[str] = None,
|
||||
) -> None:
|
||||
if message and match:
|
||||
raise TypeError(f"{self.__class__.__name__}() takes either 'message' or 'match', not both")
|
||||
|
||||
# set predicate
|
||||
if message:
|
||||
|
||||
def message_fnc(exception: BaseException) -> bool:
|
||||
return message == str(exception)
|
||||
|
||||
predicate = message_fnc
|
||||
elif match:
|
||||
prog = re.compile(match)
|
||||
|
||||
def match_fnc(exception: BaseException) -> bool:
|
||||
return bool(prog.match(str(exception)))
|
||||
|
||||
predicate = match_fnc
|
||||
else:
|
||||
raise TypeError(f"{self.__class__.__name__}() missing 1 required argument 'message' or 'match'")
|
||||
|
||||
super().__init__(predicate)
|
||||
|
||||
|
||||
class retry_if_not_exception_message(retry_if_exception_message):
|
||||
"""Retries until an exception message equals or matches."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message: typing.Optional[str] = None,
|
||||
match: typing.Optional[str] = None,
|
||||
) -> None:
|
||||
super().__init__(message, match)
|
||||
# invert predicate
|
||||
if_predicate = self.predicate
|
||||
self.predicate = lambda *args_, **kwargs_: not if_predicate(*args_, **kwargs_)
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
if retry_state.outcome is None:
|
||||
raise RuntimeError("__call__() called before outcome was set")
|
||||
|
||||
if not retry_state.outcome.failed:
|
||||
return True
|
||||
|
||||
exception = retry_state.outcome.exception()
|
||||
if exception is None:
|
||||
raise RuntimeError("outcome failed but the exception is None")
|
||||
return self.predicate(exception)
|
||||
|
||||
|
||||
class retry_any(retry_base):
|
||||
"""Retries if any of the retries condition is valid."""
|
||||
|
||||
def __init__(self, *retries: retry_base) -> None:
|
||||
self.retries = retries
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
return any(r(retry_state) for r in self.retries)
|
||||
|
||||
|
||||
class retry_all(retry_base):
|
||||
"""Retries if all the retries condition are valid."""
|
||||
|
||||
def __init__(self, *retries: retry_base) -> None:
|
||||
self.retries = retries
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
return all(r(retry_state) for r in self.retries)
|
103
venv/Lib/site-packages/pip/_vendor/tenacity/stop.py
Normal file
103
venv/Lib/site-packages/pip/_vendor/tenacity/stop.py
Normal file
@@ -0,0 +1,103 @@
|
||||
# Copyright 2016–2021 Julien Danjou
|
||||
# Copyright 2016 Joshua Harlow
|
||||
# Copyright 2013-2014 Ray Holder
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import abc
|
||||
import typing
|
||||
|
||||
from pip._vendor.tenacity import _utils
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
import threading
|
||||
|
||||
from pip._vendor.tenacity import RetryCallState
|
||||
|
||||
|
||||
class stop_base(abc.ABC):
|
||||
"""Abstract base class for stop strategies."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
pass
|
||||
|
||||
def __and__(self, other: "stop_base") -> "stop_all":
|
||||
return stop_all(self, other)
|
||||
|
||||
def __or__(self, other: "stop_base") -> "stop_any":
|
||||
return stop_any(self, other)
|
||||
|
||||
|
||||
StopBaseT = typing.Union[stop_base, typing.Callable[["RetryCallState"], bool]]
|
||||
|
||||
|
||||
class stop_any(stop_base):
|
||||
"""Stop if any of the stop condition is valid."""
|
||||
|
||||
def __init__(self, *stops: stop_base) -> None:
|
||||
self.stops = stops
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
return any(x(retry_state) for x in self.stops)
|
||||
|
||||
|
||||
class stop_all(stop_base):
|
||||
"""Stop if all the stop conditions are valid."""
|
||||
|
||||
def __init__(self, *stops: stop_base) -> None:
|
||||
self.stops = stops
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
return all(x(retry_state) for x in self.stops)
|
||||
|
||||
|
||||
class _stop_never(stop_base):
|
||||
"""Never stop."""
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
return False
|
||||
|
||||
|
||||
stop_never = _stop_never()
|
||||
|
||||
|
||||
class stop_when_event_set(stop_base):
|
||||
"""Stop when the given event is set."""
|
||||
|
||||
def __init__(self, event: "threading.Event") -> None:
|
||||
self.event = event
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
return self.event.is_set()
|
||||
|
||||
|
||||
class stop_after_attempt(stop_base):
|
||||
"""Stop when the previous attempt >= max_attempt."""
|
||||
|
||||
def __init__(self, max_attempt_number: int) -> None:
|
||||
self.max_attempt_number = max_attempt_number
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
return retry_state.attempt_number >= self.max_attempt_number
|
||||
|
||||
|
||||
class stop_after_delay(stop_base):
|
||||
"""Stop when the time from the first attempt >= limit."""
|
||||
|
||||
def __init__(self, max_delay: _utils.time_unit_type) -> None:
|
||||
self.max_delay = _utils.to_seconds(max_delay)
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> bool:
|
||||
if retry_state.seconds_since_start is None:
|
||||
raise RuntimeError("__call__() called but seconds_since_start is not set")
|
||||
return retry_state.seconds_since_start >= self.max_delay
|
59
venv/Lib/site-packages/pip/_vendor/tenacity/tornadoweb.py
Normal file
59
venv/Lib/site-packages/pip/_vendor/tenacity/tornadoweb.py
Normal file
@@ -0,0 +1,59 @@
|
||||
# Copyright 2017 Elisey Zanko
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import sys
|
||||
import typing
|
||||
|
||||
from pip._vendor.tenacity import BaseRetrying
|
||||
from pip._vendor.tenacity import DoAttempt
|
||||
from pip._vendor.tenacity import DoSleep
|
||||
from pip._vendor.tenacity import RetryCallState
|
||||
|
||||
from tornado import gen
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from tornado.concurrent import Future
|
||||
|
||||
_RetValT = typing.TypeVar("_RetValT")
|
||||
|
||||
|
||||
class TornadoRetrying(BaseRetrying):
|
||||
def __init__(self, sleep: "typing.Callable[[float], Future[None]]" = gen.sleep, **kwargs: typing.Any) -> None:
|
||||
super().__init__(**kwargs)
|
||||
self.sleep = sleep
|
||||
|
||||
@gen.coroutine # type: ignore[misc]
|
||||
def __call__(
|
||||
self,
|
||||
fn: "typing.Callable[..., typing.Union[typing.Generator[typing.Any, typing.Any, _RetValT], Future[_RetValT]]]",
|
||||
*args: typing.Any,
|
||||
**kwargs: typing.Any,
|
||||
) -> "typing.Generator[typing.Any, typing.Any, _RetValT]":
|
||||
self.begin()
|
||||
|
||||
retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs)
|
||||
while True:
|
||||
do = self.iter(retry_state=retry_state)
|
||||
if isinstance(do, DoAttempt):
|
||||
try:
|
||||
result = yield fn(*args, **kwargs)
|
||||
except BaseException: # noqa: B902
|
||||
retry_state.set_exception(sys.exc_info()) # type: ignore[arg-type]
|
||||
else:
|
||||
retry_state.set_result(result)
|
||||
elif isinstance(do, DoSleep):
|
||||
retry_state.prepare_for_next_attempt()
|
||||
yield self.sleep(do)
|
||||
else:
|
||||
raise gen.Return(do)
|
228
venv/Lib/site-packages/pip/_vendor/tenacity/wait.py
Normal file
228
venv/Lib/site-packages/pip/_vendor/tenacity/wait.py
Normal file
@@ -0,0 +1,228 @@
|
||||
# Copyright 2016–2021 Julien Danjou
|
||||
# Copyright 2016 Joshua Harlow
|
||||
# Copyright 2013-2014 Ray Holder
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import abc
|
||||
import random
|
||||
import typing
|
||||
|
||||
from pip._vendor.tenacity import _utils
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from pip._vendor.tenacity import RetryCallState
|
||||
|
||||
|
||||
class wait_base(abc.ABC):
|
||||
"""Abstract base class for wait strategies."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __call__(self, retry_state: "RetryCallState") -> float:
|
||||
pass
|
||||
|
||||
def __add__(self, other: "wait_base") -> "wait_combine":
|
||||
return wait_combine(self, other)
|
||||
|
||||
def __radd__(self, other: "wait_base") -> typing.Union["wait_combine", "wait_base"]:
|
||||
# make it possible to use multiple waits with the built-in sum function
|
||||
if other == 0: # type: ignore[comparison-overlap]
|
||||
return self
|
||||
return self.__add__(other)
|
||||
|
||||
|
||||
WaitBaseT = typing.Union[wait_base, typing.Callable[["RetryCallState"], typing.Union[float, int]]]
|
||||
|
||||
|
||||
class wait_fixed(wait_base):
|
||||
"""Wait strategy that waits a fixed amount of time between each retry."""
|
||||
|
||||
def __init__(self, wait: _utils.time_unit_type) -> None:
|
||||
self.wait_fixed = _utils.to_seconds(wait)
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> float:
|
||||
return self.wait_fixed
|
||||
|
||||
|
||||
class wait_none(wait_fixed):
|
||||
"""Wait strategy that doesn't wait at all before retrying."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(0)
|
||||
|
||||
|
||||
class wait_random(wait_base):
|
||||
"""Wait strategy that waits a random amount of time between min/max."""
|
||||
|
||||
def __init__(self, min: _utils.time_unit_type = 0, max: _utils.time_unit_type = 1) -> None: # noqa
|
||||
self.wait_random_min = _utils.to_seconds(min)
|
||||
self.wait_random_max = _utils.to_seconds(max)
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> float:
|
||||
return self.wait_random_min + (random.random() * (self.wait_random_max - self.wait_random_min))
|
||||
|
||||
|
||||
class wait_combine(wait_base):
|
||||
"""Combine several waiting strategies."""
|
||||
|
||||
def __init__(self, *strategies: wait_base) -> None:
|
||||
self.wait_funcs = strategies
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> float:
|
||||
return sum(x(retry_state=retry_state) for x in self.wait_funcs)
|
||||
|
||||
|
||||
class wait_chain(wait_base):
|
||||
"""Chain two or more waiting strategies.
|
||||
|
||||
If all strategies are exhausted, the very last strategy is used
|
||||
thereafter.
|
||||
|
||||
For example::
|
||||
|
||||
@retry(wait=wait_chain(*[wait_fixed(1) for i in range(3)] +
|
||||
[wait_fixed(2) for j in range(5)] +
|
||||
[wait_fixed(5) for k in range(4)))
|
||||
def wait_chained():
|
||||
print("Wait 1s for 3 attempts, 2s for 5 attempts and 5s
|
||||
thereafter.")
|
||||
"""
|
||||
|
||||
def __init__(self, *strategies: wait_base) -> None:
|
||||
self.strategies = strategies
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> float:
|
||||
wait_func_no = min(max(retry_state.attempt_number, 1), len(self.strategies))
|
||||
wait_func = self.strategies[wait_func_no - 1]
|
||||
return wait_func(retry_state=retry_state)
|
||||
|
||||
|
||||
class wait_incrementing(wait_base):
|
||||
"""Wait an incremental amount of time after each attempt.
|
||||
|
||||
Starting at a starting value and incrementing by a value for each attempt
|
||||
(and restricting the upper limit to some maximum value).
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
start: _utils.time_unit_type = 0,
|
||||
increment: _utils.time_unit_type = 100,
|
||||
max: _utils.time_unit_type = _utils.MAX_WAIT, # noqa
|
||||
) -> None:
|
||||
self.start = _utils.to_seconds(start)
|
||||
self.increment = _utils.to_seconds(increment)
|
||||
self.max = _utils.to_seconds(max)
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> float:
|
||||
result = self.start + (self.increment * (retry_state.attempt_number - 1))
|
||||
return max(0, min(result, self.max))
|
||||
|
||||
|
||||
class wait_exponential(wait_base):
|
||||
"""Wait strategy that applies exponential backoff.
|
||||
|
||||
It allows for a customized multiplier and an ability to restrict the
|
||||
upper and lower limits to some maximum and minimum value.
|
||||
|
||||
The intervals are fixed (i.e. there is no jitter), so this strategy is
|
||||
suitable for balancing retries against latency when a required resource is
|
||||
unavailable for an unknown duration, but *not* suitable for resolving
|
||||
contention between multiple processes for a shared resource. Use
|
||||
wait_random_exponential for the latter case.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
multiplier: typing.Union[int, float] = 1,
|
||||
max: _utils.time_unit_type = _utils.MAX_WAIT, # noqa
|
||||
exp_base: typing.Union[int, float] = 2,
|
||||
min: _utils.time_unit_type = 0, # noqa
|
||||
) -> None:
|
||||
self.multiplier = multiplier
|
||||
self.min = _utils.to_seconds(min)
|
||||
self.max = _utils.to_seconds(max)
|
||||
self.exp_base = exp_base
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> float:
|
||||
try:
|
||||
exp = self.exp_base ** (retry_state.attempt_number - 1)
|
||||
result = self.multiplier * exp
|
||||
except OverflowError:
|
||||
return self.max
|
||||
return max(max(0, self.min), min(result, self.max))
|
||||
|
||||
|
||||
class wait_random_exponential(wait_exponential):
|
||||
"""Random wait with exponentially widening window.
|
||||
|
||||
An exponential backoff strategy used to mediate contention between multiple
|
||||
uncoordinated processes for a shared resource in distributed systems. This
|
||||
is the sense in which "exponential backoff" is meant in e.g. Ethernet
|
||||
networking, and corresponds to the "Full Jitter" algorithm described in
|
||||
this blog post:
|
||||
|
||||
https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
|
||||
|
||||
Each retry occurs at a random time in a geometrically expanding interval.
|
||||
It allows for a custom multiplier and an ability to restrict the upper
|
||||
limit of the random interval to some maximum value.
|
||||
|
||||
Example::
|
||||
|
||||
wait_random_exponential(multiplier=0.5, # initial window 0.5s
|
||||
max=60) # max 60s timeout
|
||||
|
||||
When waiting for an unavailable resource to become available again, as
|
||||
opposed to trying to resolve contention for a shared resource, the
|
||||
wait_exponential strategy (which uses a fixed interval) may be preferable.
|
||||
|
||||
"""
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> float:
|
||||
high = super().__call__(retry_state=retry_state)
|
||||
return random.uniform(0, high)
|
||||
|
||||
|
||||
class wait_exponential_jitter(wait_base):
|
||||
"""Wait strategy that applies exponential backoff and jitter.
|
||||
|
||||
It allows for a customized initial wait, maximum wait and jitter.
|
||||
|
||||
This implements the strategy described here:
|
||||
https://cloud.google.com/storage/docs/retry-strategy
|
||||
|
||||
The wait time is min(initial * 2**n + random.uniform(0, jitter), maximum)
|
||||
where n is the retry count.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
initial: float = 1,
|
||||
max: float = _utils.MAX_WAIT, # noqa
|
||||
exp_base: float = 2,
|
||||
jitter: float = 1,
|
||||
) -> None:
|
||||
self.initial = initial
|
||||
self.max = max
|
||||
self.exp_base = exp_base
|
||||
self.jitter = jitter
|
||||
|
||||
def __call__(self, retry_state: "RetryCallState") -> float:
|
||||
jitter = random.uniform(0, self.jitter)
|
||||
try:
|
||||
exp = self.exp_base ** (retry_state.attempt_number - 1)
|
||||
result = self.initial * exp + jitter
|
||||
except OverflowError:
|
||||
result = self.max
|
||||
return max(0, min(result, self.max))
|
Reference in New Issue
Block a user