Skip to content

Commit d2852d0

Browse files
committed
Upgrade tenacity to 8.2.2
1 parent d7e0248 commit d2852d0

File tree

13 files changed

+282
-124
lines changed

13 files changed

+282
-124
lines changed

news/tenacity.vendor.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade tenacity to 8.2.2

src/pip/_vendor/tenacity/__init__.py

Lines changed: 154 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# See the License for the specific language governing permissions and
1717
# limitations under the License.
1818

19+
1920
import functools
2021
import sys
2122
import threading
@@ -88,51 +89,13 @@
8889
if t.TYPE_CHECKING:
8990
import types
9091

91-
from .wait import wait_base
92-
from .stop import stop_base
93-
94-
95-
WrappedFn = t.TypeVar("WrappedFn", bound=t.Callable)
96-
_RetValT = t.TypeVar("_RetValT")
97-
98-
99-
@t.overload
100-
def retry(fn: WrappedFn) -> WrappedFn:
101-
pass
102-
103-
104-
@t.overload
105-
def retry(*dargs: t.Any, **dkw: t.Any) -> t.Callable[[WrappedFn], WrappedFn]: # noqa
106-
pass
107-
108-
109-
def retry(*dargs: t.Any, **dkw: t.Any) -> t.Union[WrappedFn, t.Callable[[WrappedFn], WrappedFn]]: # noqa
110-
"""Wrap a function with a new `Retrying` object.
111-
112-
:param dargs: positional arguments passed to Retrying object
113-
:param dkw: keyword arguments passed to the Retrying object
114-
"""
115-
# support both @retry and @retry() as valid syntax
116-
if len(dargs) == 1 and callable(dargs[0]):
117-
return retry()(dargs[0])
118-
else:
119-
120-
def wrap(f: WrappedFn) -> WrappedFn:
121-
if isinstance(f, retry_base):
122-
warnings.warn(
123-
f"Got retry_base instance ({f.__class__.__name__}) as callable argument, "
124-
f"this will probably hang indefinitely (did you mean retry={f.__class__.__name__}(...)?)"
125-
)
126-
if iscoroutinefunction(f):
127-
r: "BaseRetrying" = AsyncRetrying(*dargs, **dkw)
128-
elif tornado and hasattr(tornado.gen, "is_coroutine_function") and tornado.gen.is_coroutine_function(f):
129-
r = TornadoRetrying(*dargs, **dkw)
130-
else:
131-
r = Retrying(*dargs, **dkw)
92+
from .retry import RetryBaseT
93+
from .stop import StopBaseT
94+
from .wait import WaitBaseT
13295

133-
return r.wraps(f)
13496

135-
return wrap
97+
WrappedFnReturnT = t.TypeVar("WrappedFnReturnT")
98+
WrappedFn = t.TypeVar("WrappedFn", bound=t.Callable[..., t.Any])
13699

137100

138101
class TryAgain(Exception):
@@ -216,7 +179,7 @@ def __exit__(
216179
exc_value: t.Optional[BaseException],
217180
traceback: t.Optional["types.TracebackType"],
218181
) -> t.Optional[bool]:
219-
if isinstance(exc_value, BaseException):
182+
if exc_type is not None and exc_value is not None:
220183
self.retry_state.set_exception((exc_type, exc_value, traceback))
221184
return True # Swallow exception.
222185
else:
@@ -229,9 +192,9 @@ class BaseRetrying(ABC):
229192
def __init__(
230193
self,
231194
sleep: t.Callable[[t.Union[int, float]], None] = sleep,
232-
stop: "stop_base" = stop_never,
233-
wait: "wait_base" = wait_none(),
234-
retry: retry_base = retry_if_exception_type(),
195+
stop: "StopBaseT" = stop_never,
196+
wait: "WaitBaseT" = wait_none(),
197+
retry: "RetryBaseT" = retry_if_exception_type(),
235198
before: t.Callable[["RetryCallState"], None] = before_nothing,
236199
after: t.Callable[["RetryCallState"], None] = after_nothing,
237200
before_sleep: t.Optional[t.Callable[["RetryCallState"], None]] = None,
@@ -254,8 +217,8 @@ def __init__(
254217
def copy(
255218
self,
256219
sleep: t.Union[t.Callable[[t.Union[int, float]], None], object] = _unset,
257-
stop: t.Union["stop_base", object] = _unset,
258-
wait: t.Union["wait_base", object] = _unset,
220+
stop: t.Union["StopBaseT", object] = _unset,
221+
wait: t.Union["WaitBaseT", object] = _unset,
259222
retry: t.Union[retry_base, object] = _unset,
260223
before: t.Union[t.Callable[["RetryCallState"], None], object] = _unset,
261224
after: t.Union[t.Callable[["RetryCallState"], None], object] = _unset,
@@ -312,9 +275,9 @@ def statistics(self) -> t.Dict[str, t.Any]:
312275
statistics from each thread).
313276
"""
314277
try:
315-
return self._local.statistics
278+
return self._local.statistics # type: ignore[no-any-return]
316279
except AttributeError:
317-
self._local.statistics = {}
280+
self._local.statistics = t.cast(t.Dict[str, t.Any], {})
318281
return self._local.statistics
319282

320283
def wraps(self, f: WrappedFn) -> WrappedFn:
@@ -330,10 +293,10 @@ def wrapped_f(*args: t.Any, **kw: t.Any) -> t.Any:
330293
def retry_with(*args: t.Any, **kwargs: t.Any) -> WrappedFn:
331294
return self.copy(*args, **kwargs).wraps(f)
332295

333-
wrapped_f.retry = self
334-
wrapped_f.retry_with = retry_with
296+
wrapped_f.retry = self # type: ignore[attr-defined]
297+
wrapped_f.retry_with = retry_with # type: ignore[attr-defined]
335298

336-
return wrapped_f
299+
return wrapped_f # type: ignore[return-value]
337300

338301
def begin(self) -> None:
339302
self.statistics.clear()
@@ -348,15 +311,15 @@ def iter(self, retry_state: "RetryCallState") -> t.Union[DoAttempt, DoSleep, t.A
348311
self.before(retry_state)
349312
return DoAttempt()
350313

351-
is_explicit_retry = retry_state.outcome.failed and isinstance(retry_state.outcome.exception(), TryAgain)
352-
if not (is_explicit_retry or self.retry(retry_state=retry_state)):
314+
is_explicit_retry = fut.failed and isinstance(fut.exception(), TryAgain)
315+
if not (is_explicit_retry or self.retry(retry_state)):
353316
return fut.result()
354317

355318
if self.after is not None:
356319
self.after(retry_state)
357320

358321
self.statistics["delay_since_first_attempt"] = retry_state.seconds_since_start
359-
if self.stop(retry_state=retry_state):
322+
if self.stop(retry_state):
360323
if self.retry_error_callback:
361324
return self.retry_error_callback(retry_state)
362325
retry_exc = self.retry_error_cls(fut)
@@ -365,7 +328,7 @@ def iter(self, retry_state: "RetryCallState") -> t.Union[DoAttempt, DoSleep, t.A
365328
raise retry_exc from fut.exception()
366329

367330
if self.wait:
368-
sleep = self.wait(retry_state=retry_state)
331+
sleep = self.wait(retry_state)
369332
else:
370333
sleep = 0.0
371334
retry_state.next_action = RetryAction(sleep)
@@ -393,14 +356,24 @@ def __iter__(self) -> t.Generator[AttemptManager, None, None]:
393356
break
394357

395358
@abstractmethod
396-
def __call__(self, fn: t.Callable[..., _RetValT], *args: t.Any, **kwargs: t.Any) -> _RetValT:
359+
def __call__(
360+
self,
361+
fn: t.Callable[..., WrappedFnReturnT],
362+
*args: t.Any,
363+
**kwargs: t.Any,
364+
) -> WrappedFnReturnT:
397365
pass
398366

399367

400368
class Retrying(BaseRetrying):
401369
"""Retrying controller."""
402370

403-
def __call__(self, fn: t.Callable[..., _RetValT], *args: t.Any, **kwargs: t.Any) -> _RetValT:
371+
def __call__(
372+
self,
373+
fn: t.Callable[..., WrappedFnReturnT],
374+
*args: t.Any,
375+
**kwargs: t.Any,
376+
) -> WrappedFnReturnT:
404377
self.begin()
405378

406379
retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs)
@@ -410,17 +383,23 @@ def __call__(self, fn: t.Callable[..., _RetValT], *args: t.Any, **kwargs: t.Any)
410383
try:
411384
result = fn(*args, **kwargs)
412385
except BaseException: # noqa: B902
413-
retry_state.set_exception(sys.exc_info())
386+
retry_state.set_exception(sys.exc_info()) # type: ignore[arg-type]
414387
else:
415388
retry_state.set_result(result)
416389
elif isinstance(do, DoSleep):
417390
retry_state.prepare_for_next_attempt()
418391
self.sleep(do)
419392
else:
420-
return do
393+
return do # type: ignore[no-any-return]
394+
395+
396+
if sys.version_info[1] >= 9:
397+
FutureGenericT = futures.Future[t.Any]
398+
else:
399+
FutureGenericT = futures.Future
421400

422401

423-
class Future(futures.Future):
402+
class Future(FutureGenericT):
424403
"""Encapsulates a (future or past) attempted call to a target function."""
425404

426405
def __init__(self, attempt_number: int) -> None:
@@ -493,13 +472,15 @@ def set_result(self, val: t.Any) -> None:
493472
fut.set_result(val)
494473
self.outcome, self.outcome_timestamp = fut, ts
495474

496-
def set_exception(self, exc_info: t.Tuple[t.Type[BaseException], BaseException, "types.TracebackType"]) -> None:
475+
def set_exception(
476+
self, exc_info: t.Tuple[t.Type[BaseException], BaseException, "types.TracebackType| None"]
477+
) -> None:
497478
ts = time.monotonic()
498479
fut = Future(self.attempt_number)
499480
fut.set_exception(exc_info[1])
500481
self.outcome, self.outcome_timestamp = fut, ts
501482

502-
def __repr__(self):
483+
def __repr__(self) -> str:
503484
if self.outcome is None:
504485
result = "none yet"
505486
elif self.outcome.failed:
@@ -513,7 +494,115 @@ def __repr__(self):
513494
return f"<{clsname} {id(self)}: attempt #{self.attempt_number}; slept for {slept}; last result: {result}>"
514495

515496

497+
@t.overload
498+
def retry(func: WrappedFn) -> WrappedFn:
499+
...
500+
501+
502+
@t.overload
503+
def retry(
504+
sleep: t.Callable[[t.Union[int, float]], None] = sleep,
505+
stop: "StopBaseT" = stop_never,
506+
wait: "WaitBaseT" = wait_none(),
507+
retry: "RetryBaseT" = retry_if_exception_type(),
508+
before: t.Callable[["RetryCallState"], None] = before_nothing,
509+
after: t.Callable[["RetryCallState"], None] = after_nothing,
510+
before_sleep: t.Optional[t.Callable[["RetryCallState"], None]] = None,
511+
reraise: bool = False,
512+
retry_error_cls: t.Type["RetryError"] = RetryError,
513+
retry_error_callback: t.Optional[t.Callable[["RetryCallState"], t.Any]] = None,
514+
) -> t.Callable[[WrappedFn], WrappedFn]:
515+
...
516+
517+
518+
def retry(*dargs: t.Any, **dkw: t.Any) -> t.Any:
519+
"""Wrap a function with a new `Retrying` object.
520+
521+
:param dargs: positional arguments passed to Retrying object
522+
:param dkw: keyword arguments passed to the Retrying object
523+
"""
524+
# support both @retry and @retry() as valid syntax
525+
if len(dargs) == 1 and callable(dargs[0]):
526+
return retry()(dargs[0])
527+
else:
528+
529+
def wrap(f: WrappedFn) -> WrappedFn:
530+
if isinstance(f, retry_base):
531+
warnings.warn(
532+
f"Got retry_base instance ({f.__class__.__name__}) as callable argument, "
533+
f"this will probably hang indefinitely (did you mean retry={f.__class__.__name__}(...)?)"
534+
)
535+
r: "BaseRetrying"
536+
if iscoroutinefunction(f):
537+
r = AsyncRetrying(*dargs, **dkw)
538+
elif tornado and hasattr(tornado.gen, "is_coroutine_function") and tornado.gen.is_coroutine_function(f):
539+
r = TornadoRetrying(*dargs, **dkw)
540+
else:
541+
r = Retrying(*dargs, **dkw)
542+
543+
return r.wraps(f)
544+
545+
return wrap
546+
547+
516548
from pip._vendor.tenacity._asyncio import AsyncRetrying # noqa:E402,I100
517549

518550
if tornado:
519551
from pip._vendor.tenacity.tornadoweb import TornadoRetrying
552+
553+
554+
__all__ = [
555+
"retry_base",
556+
"retry_all",
557+
"retry_always",
558+
"retry_any",
559+
"retry_if_exception",
560+
"retry_if_exception_type",
561+
"retry_if_exception_cause_type",
562+
"retry_if_not_exception_type",
563+
"retry_if_not_result",
564+
"retry_if_result",
565+
"retry_never",
566+
"retry_unless_exception_type",
567+
"retry_if_exception_message",
568+
"retry_if_not_exception_message",
569+
"sleep",
570+
"sleep_using_event",
571+
"stop_after_attempt",
572+
"stop_after_delay",
573+
"stop_all",
574+
"stop_any",
575+
"stop_never",
576+
"stop_when_event_set",
577+
"wait_chain",
578+
"wait_combine",
579+
"wait_exponential",
580+
"wait_fixed",
581+
"wait_incrementing",
582+
"wait_none",
583+
"wait_random",
584+
"wait_random_exponential",
585+
"wait_full_jitter",
586+
"wait_exponential_jitter",
587+
"before_log",
588+
"before_nothing",
589+
"after_log",
590+
"after_nothing",
591+
"before_sleep_log",
592+
"before_sleep_nothing",
593+
"retry",
594+
"WrappedFn",
595+
"TryAgain",
596+
"NO_RESULT",
597+
"DoAttempt",
598+
"DoSleep",
599+
"BaseAction",
600+
"RetryAction",
601+
"RetryError",
602+
"AttemptManager",
603+
"BaseRetrying",
604+
"Retrying",
605+
"Future",
606+
"RetryCallState",
607+
"AsyncRetrying",
608+
]

0 commit comments

Comments
 (0)