python-backoff 2.3.0__py3-none-any.whl → 2.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
backoff/__init__.py CHANGED
@@ -1,4 +1,3 @@
1
- # coding:utf-8
2
1
  """
3
2
  Function decoration for backoff and retry
4
3
 
@@ -12,20 +11,21 @@ polling resources for externally generated content.
12
11
  For examples and full documentation see the README at
13
12
  https://github.com/python-backoff/backoff
14
13
  """
14
+
15
15
  from backoff._decorator import on_exception, on_predicate
16
16
  from backoff._jitter import full_jitter, random_jitter
17
17
  from backoff._wait_gen import constant, expo, fibo, runtime, decay
18
18
 
19
19
  __all__ = [
20
- 'on_predicate',
21
- 'on_exception',
22
- 'constant',
23
- 'expo',
24
- 'decay',
25
- 'fibo',
26
- 'runtime',
27
- 'full_jitter',
28
- 'random_jitter',
20
+ "on_predicate",
21
+ "on_exception",
22
+ "constant",
23
+ "expo",
24
+ "decay",
25
+ "fibo",
26
+ "runtime",
27
+ "full_jitter",
28
+ "random_jitter",
29
29
  ]
30
30
 
31
- __version__ = "2.2.1"
31
+ __version__ = "2.3.1"
backoff/_async.py CHANGED
@@ -1,4 +1,3 @@
1
- # coding:utf-8
2
1
  import asyncio
3
2
  import functools
4
3
  import inspect
@@ -11,9 +10,11 @@ def _ensure_coroutine(coro_or_func):
11
10
  if inspect.iscoroutinefunction(coro_or_func):
12
11
  return coro_or_func
13
12
  else:
13
+
14
14
  @functools.wraps(coro_or_func)
15
15
  async def f(*args, **kwargs):
16
16
  return coro_or_func(*args, **kwargs)
17
+
17
18
  return f
18
19
 
19
20
 
@@ -21,27 +22,32 @@ def _ensure_coroutines(coros_or_funcs):
21
22
  return [_ensure_coroutine(f) for f in coros_or_funcs]
22
23
 
23
24
 
24
- async def _call_handlers(handlers,
25
- *,
26
- target, args, kwargs, tries, elapsed,
27
- **extra):
25
+ async def _call_handlers(handlers, *, target, args, kwargs, tries, elapsed, **extra):
28
26
  details = {
29
- 'target': target,
30
- 'args': args,
31
- 'kwargs': kwargs,
32
- 'tries': tries,
33
- 'elapsed': elapsed,
27
+ "target": target,
28
+ "args": args,
29
+ "kwargs": kwargs,
30
+ "tries": tries,
31
+ "elapsed": elapsed,
34
32
  }
35
33
  details.update(extra)
36
34
  for handler in handlers:
37
35
  await handler(details)
38
36
 
39
37
 
40
- def retry_predicate(target, wait_gen, predicate,
41
- *,
42
- max_tries, max_time, jitter,
43
- on_success, on_backoff, on_giveup,
44
- wait_gen_kwargs):
38
+ def retry_predicate(
39
+ target,
40
+ wait_gen,
41
+ predicate,
42
+ *,
43
+ max_tries,
44
+ max_time,
45
+ jitter,
46
+ on_success,
47
+ on_backoff,
48
+ on_giveup,
49
+ wait_gen_kwargs,
50
+ ):
45
51
  on_success = _ensure_coroutines(on_success)
46
52
  on_backoff = _ensure_coroutines(on_backoff)
47
53
  on_giveup = _ensure_coroutines(on_giveup)
@@ -54,7 +60,6 @@ def retry_predicate(target, wait_gen, predicate,
54
60
 
55
61
  @functools.wraps(target)
56
62
  async def retry(*args, **kwargs):
57
-
58
63
  # update variables from outer function args
59
64
  max_tries_value = _maybe_call(max_tries)
60
65
  max_time_value = _maybe_call(max_time)
@@ -75,23 +80,22 @@ def retry_predicate(target, wait_gen, predicate,
75
80
 
76
81
  ret = await target(*args, **kwargs)
77
82
  if predicate(ret):
78
- max_tries_exceeded = (tries == max_tries_value)
79
- max_time_exceeded = (max_time_value is not None and
80
- elapsed >= max_time_value)
83
+ max_tries_exceeded = tries == max_tries_value
84
+ max_time_exceeded = (
85
+ max_time_value is not None and elapsed >= max_time_value
86
+ )
81
87
 
82
88
  if max_tries_exceeded or max_time_exceeded:
83
89
  await _call_handlers(on_giveup, **details, value=ret)
84
90
  break
85
91
 
86
92
  try:
87
- seconds = _next_wait(wait, ret, jitter, elapsed,
88
- max_time_value)
93
+ seconds = _next_wait(wait, ret, jitter, elapsed, max_time_value)
89
94
  except StopIteration:
90
95
  await _call_handlers(on_giveup, **details, value=ret)
91
96
  break
92
97
 
93
- await _call_handlers(on_backoff, **details, value=ret,
94
- wait=seconds)
98
+ await _call_handlers(on_backoff, **details, value=ret, wait=seconds)
95
99
 
96
100
  # Note: there is no convenient way to pass explicit event
97
101
  # loop to decorator, so here we assume that either default
@@ -113,11 +117,21 @@ def retry_predicate(target, wait_gen, predicate,
113
117
  return retry
114
118
 
115
119
 
116
- def retry_exception(target, wait_gen, exception,
117
- *,
118
- max_tries, max_time, jitter, giveup,
119
- on_success, on_backoff, on_giveup, raise_on_giveup,
120
- wait_gen_kwargs):
120
+ def retry_exception(
121
+ target,
122
+ wait_gen,
123
+ exception,
124
+ *,
125
+ max_tries,
126
+ max_time,
127
+ jitter,
128
+ giveup,
129
+ on_success,
130
+ on_backoff,
131
+ on_giveup,
132
+ raise_on_giveup,
133
+ wait_gen_kwargs,
134
+ ):
121
135
  on_success = _ensure_coroutines(on_success)
122
136
  on_backoff = _ensure_coroutines(on_backoff)
123
137
  on_giveup = _ensure_coroutines(on_giveup)
@@ -129,7 +143,6 @@ def retry_exception(target, wait_gen, exception,
129
143
 
130
144
  @functools.wraps(target)
131
145
  async def retry(*args, **kwargs):
132
-
133
146
  max_tries_value = _maybe_call(max_tries)
134
147
  max_time_value = _maybe_call(max_time)
135
148
 
@@ -151,9 +164,10 @@ def retry_exception(target, wait_gen, exception,
151
164
  ret = await target(*args, **kwargs)
152
165
  except exception as e:
153
166
  giveup_result = await giveup(e)
154
- max_tries_exceeded = (tries == max_tries_value)
155
- max_time_exceeded = (max_time_value is not None and
156
- elapsed >= max_time_value)
167
+ max_tries_exceeded = tries == max_tries_value
168
+ max_time_exceeded = (
169
+ max_time_value is not None and elapsed >= max_time_value
170
+ )
157
171
 
158
172
  if giveup_result or max_tries_exceeded or max_time_exceeded:
159
173
  await _call_handlers(on_giveup, **details, exception=e)
@@ -162,14 +176,12 @@ def retry_exception(target, wait_gen, exception,
162
176
  return None
163
177
 
164
178
  try:
165
- seconds = _next_wait(wait, e, jitter, elapsed,
166
- max_time_value)
179
+ seconds = _next_wait(wait, e, jitter, elapsed, max_time_value)
167
180
  except StopIteration:
168
181
  await _call_handlers(on_giveup, **details, exception=e)
169
182
  raise e
170
183
 
171
- await _call_handlers(on_backoff, **details, wait=seconds,
172
- exception=e)
184
+ await _call_handlers(on_backoff, **details, wait=seconds, exception=e)
173
185
 
174
186
  # Note: there is no convenient way to pass explicit event
175
187
  # loop to decorator, so here we assume that either default
@@ -185,4 +197,5 @@ def retry_exception(target, wait_gen, exception,
185
197
  await _call_handlers(on_success, **details)
186
198
 
187
199
  return ret
200
+
188
201
  return retry
backoff/_common.py CHANGED
@@ -1,5 +1,3 @@
1
- # coding:utf-8
2
-
3
1
  import functools
4
2
  import logging
5
3
  import sys
@@ -8,7 +6,7 @@ import warnings
8
6
 
9
7
 
10
8
  # Use module-specific logger with a default null handler.
11
- _logger = logging.getLogger('backoff')
9
+ _logger = logging.getLogger("backoff")
12
10
  _logger.addHandler(logging.NullHandler()) # pragma: no cover
13
11
  _logger.setLevel(logging.INFO)
14
12
 
@@ -34,10 +32,7 @@ def _init_wait_gen(wait_gen, wait_gen_kwargs):
34
32
  def _next_wait(wait, send_value, jitter, elapsed, max_time):
35
33
  value = wait.send(send_value)
36
34
  try:
37
- if jitter is not None:
38
- seconds = jitter(value)
39
- else:
40
- seconds = value
35
+ seconds = jitter(value) if jitter is not None else value
41
36
  except TypeError:
42
37
  warnings.warn(
43
38
  "Nullary jitter function signature is deprecated. Use "
@@ -65,14 +60,20 @@ def _prepare_logger(logger):
65
60
  # Configure handler list with user specified handler and optionally
66
61
  # with a default handler bound to the specified logger.
67
62
  def _config_handlers(
68
- user_handlers, *, default_handler=None, logger=None, log_level=None,
63
+ user_handlers,
64
+ *,
65
+ default_handler=None,
66
+ logger=None,
67
+ log_level=None,
69
68
  ):
70
69
  handlers = []
71
70
  if logger is not None:
72
71
  assert log_level is not None, "Log level is not specified"
73
72
  # bind the specified logger to the default log handler
74
73
  log_handler = functools.partial(
75
- default_handler, logger=logger, log_level=log_level,
74
+ default_handler,
75
+ logger=logger,
76
+ log_level=log_level,
76
77
  )
77
78
  handlers.append(log_handler)
78
79
 
@@ -81,7 +82,7 @@ def _config_handlers(
81
82
 
82
83
  # user specified handlers can either be an iterable of handlers
83
84
  # or a single handler. either way append them to the list.
84
- if hasattr(user_handlers, '__iter__'):
85
+ if hasattr(user_handlers, "__iter__"):
85
86
  # add all handlers in the iterable
86
87
  handlers += list(user_handlers)
87
88
  else:
@@ -94,27 +95,27 @@ def _config_handlers(
94
95
  # Default backoff handler
95
96
  def _log_backoff(details, logger, log_level):
96
97
  msg = "Backing off %s(...) for %.1fs (%s)"
97
- log_args = [details['target'].__name__, details['wait']]
98
+ log_args = [details["target"].__name__, details["wait"]]
98
99
 
99
100
  exc_typ, exc, _ = sys.exc_info()
100
101
  if exc is not None:
101
102
  exc_fmt = traceback.format_exception_only(exc_typ, exc)[-1]
102
103
  log_args.append(exc_fmt.rstrip("\n"))
103
104
  else:
104
- log_args.append(details['value'])
105
+ log_args.append(details["value"])
105
106
  logger.log(log_level, msg, *log_args)
106
107
 
107
108
 
108
109
  # Default giveup handler
109
110
  def _log_giveup(details, logger, log_level):
110
111
  msg = "Giving up %s(...) after %d tries (%s)"
111
- log_args = [details['target'].__name__, details['tries']]
112
+ log_args = [details["target"].__name__, details["tries"]]
112
113
 
113
114
  exc_typ, exc, _ = sys.exc_info()
114
115
  if exc is not None:
115
116
  exc_fmt = traceback.format_exception_only(exc_typ, exc)[-1]
116
117
  log_args.append(exc_fmt.rstrip("\n"))
117
118
  else:
118
- log_args.append(details['value'])
119
+ log_args.append(details["value"])
119
120
 
120
121
  logger.log(log_level, msg, *log_args)
backoff/_decorator.py CHANGED
@@ -1,4 +1,3 @@
1
- # coding:utf-8
2
1
  import inspect
3
2
  import logging
4
3
  import operator
@@ -24,19 +23,21 @@ from backoff._typing import (
24
23
  )
25
24
 
26
25
 
27
- def on_predicate(wait_gen: _WaitGenerator,
28
- predicate: _Predicate[Any] = operator.not_,
29
- *,
30
- max_tries: Optional[_MaybeCallable[int]] = None,
31
- max_time: Optional[_MaybeCallable[float]] = None,
32
- jitter: Union[_Jitterer, None] = full_jitter,
33
- on_success: Union[_Handler, Iterable[_Handler], None] = None,
34
- on_backoff: Union[_Handler, Iterable[_Handler], None] = None,
35
- on_giveup: Union[_Handler, Iterable[_Handler], None] = None,
36
- logger: _MaybeLogger = 'backoff',
37
- backoff_log_level: int = logging.INFO,
38
- giveup_log_level: int = logging.ERROR,
39
- **wait_gen_kwargs: Any) -> Callable[[_CallableT], _CallableT]:
26
+ def on_predicate(
27
+ wait_gen: _WaitGenerator,
28
+ predicate: _Predicate[Any] = operator.not_,
29
+ *,
30
+ max_tries: Optional[_MaybeCallable[int]] = None,
31
+ max_time: Optional[_MaybeCallable[float]] = None,
32
+ jitter: Union[_Jitterer, None] = full_jitter,
33
+ on_success: Union[_Handler, Iterable[_Handler], None] = None,
34
+ on_backoff: Union[_Handler, Iterable[_Handler], None] = None,
35
+ on_giveup: Union[_Handler, Iterable[_Handler], None] = None,
36
+ logger: _MaybeLogger = "backoff",
37
+ backoff_log_level: int = logging.INFO,
38
+ giveup_log_level: int = logging.ERROR,
39
+ **wait_gen_kwargs: Any,
40
+ ) -> Callable[[_CallableT], _CallableT]:
40
41
  """Returns decorator for backoff and retry triggered by predicate.
41
42
 
42
43
  Args:
@@ -80,6 +81,7 @@ def on_predicate(wait_gen: _WaitGenerator,
80
81
  args will first be evaluated and their return values passed.
81
82
  This is useful for runtime configuration.
82
83
  """
84
+
83
85
  def decorate(target):
84
86
  nonlocal logger, on_success, on_backoff, on_giveup
85
87
 
@@ -120,21 +122,23 @@ def on_predicate(wait_gen: _WaitGenerator,
120
122
  return decorate
121
123
 
122
124
 
123
- def on_exception(wait_gen: _WaitGenerator,
124
- exception: _MaybeSequence[Type[Exception]],
125
- *,
126
- max_tries: Optional[_MaybeCallable[int]] = None,
127
- max_time: Optional[_MaybeCallable[float]] = None,
128
- jitter: Union[_Jitterer, None] = full_jitter,
129
- giveup: _Predicate[Exception] = lambda e: False,
130
- on_success: Union[_Handler, Iterable[_Handler], None] = None,
131
- on_backoff: Union[_Handler, Iterable[_Handler], None] = None,
132
- on_giveup: Union[_Handler, Iterable[_Handler], None] = None,
133
- raise_on_giveup: bool = True,
134
- logger: _MaybeLogger = 'backoff',
135
- backoff_log_level: int = logging.INFO,
136
- giveup_log_level: int = logging.ERROR,
137
- **wait_gen_kwargs: Any) -> Callable[[_CallableT], _CallableT]:
125
+ def on_exception(
126
+ wait_gen: _WaitGenerator,
127
+ exception: _MaybeSequence[Type[Exception]],
128
+ *,
129
+ max_tries: Optional[_MaybeCallable[int]] = None,
130
+ max_time: Optional[_MaybeCallable[float]] = None,
131
+ jitter: Union[_Jitterer, None] = full_jitter,
132
+ giveup: _Predicate[Exception] = lambda e: False,
133
+ on_success: Union[_Handler, Iterable[_Handler], None] = None,
134
+ on_backoff: Union[_Handler, Iterable[_Handler], None] = None,
135
+ on_giveup: Union[_Handler, Iterable[_Handler], None] = None,
136
+ raise_on_giveup: bool = True,
137
+ logger: _MaybeLogger = "backoff",
138
+ backoff_log_level: int = logging.INFO,
139
+ giveup_log_level: int = logging.ERROR,
140
+ **wait_gen_kwargs: Any,
141
+ ) -> Callable[[_CallableT], _CallableT]:
138
142
  """Returns decorator for backoff and retry triggered by exception.
139
143
 
140
144
  Args:
@@ -180,6 +184,7 @@ def on_exception(wait_gen: _WaitGenerator,
180
184
  args will first be evaluated and their return values passed.
181
185
  This is useful for runtime configuration.
182
186
  """
187
+
183
188
  def decorate(target):
184
189
  nonlocal logger, on_success, on_backoff, on_giveup
185
190
 
backoff/_jitter.py CHANGED
@@ -1,5 +1,3 @@
1
- # coding:utf-8
2
-
3
1
  import random
4
2
 
5
3
 
backoff/_sync.py CHANGED
@@ -1,29 +1,35 @@
1
- # coding:utf-8
2
1
  import functools
3
2
  import time
4
3
 
5
- from backoff._common import (_init_wait_gen, _maybe_call, _next_wait)
4
+ from backoff._common import _init_wait_gen, _maybe_call, _next_wait
6
5
 
7
6
 
8
7
  def _call_handlers(hdlrs, target, args, kwargs, tries, elapsed, **extra):
9
8
  details = {
10
- 'target': target,
11
- 'args': args,
12
- 'kwargs': kwargs,
13
- 'tries': tries,
14
- 'elapsed': elapsed,
9
+ "target": target,
10
+ "args": args,
11
+ "kwargs": kwargs,
12
+ "tries": tries,
13
+ "elapsed": elapsed,
15
14
  }
16
15
  details.update(extra)
17
16
  for hdlr in hdlrs:
18
17
  hdlr(details)
19
18
 
20
19
 
21
- def retry_predicate(target, wait_gen, predicate,
22
- *,
23
- max_tries, max_time, jitter,
24
- on_success, on_backoff, on_giveup,
25
- wait_gen_kwargs):
26
-
20
+ def retry_predicate(
21
+ target,
22
+ wait_gen,
23
+ predicate,
24
+ *,
25
+ max_tries,
26
+ max_time,
27
+ jitter,
28
+ on_success,
29
+ on_backoff,
30
+ on_giveup,
31
+ wait_gen_kwargs,
32
+ ):
27
33
  @functools.wraps(target)
28
34
  def retry(*args, **kwargs):
29
35
  max_tries_value = _maybe_call(max_tries)
@@ -45,23 +51,22 @@ def retry_predicate(target, wait_gen, predicate,
45
51
 
46
52
  ret = target(*args, **kwargs)
47
53
  if predicate(ret):
48
- max_tries_exceeded = (tries == max_tries_value)
49
- max_time_exceeded = (max_time_value is not None and
50
- elapsed >= max_time_value)
54
+ max_tries_exceeded = tries == max_tries_value
55
+ max_time_exceeded = (
56
+ max_time_value is not None and elapsed >= max_time_value
57
+ )
51
58
 
52
59
  if max_tries_exceeded or max_time_exceeded:
53
60
  _call_handlers(on_giveup, **details, value=ret)
54
61
  break
55
62
 
56
63
  try:
57
- seconds = _next_wait(wait, ret, jitter, elapsed,
58
- max_time_value)
64
+ seconds = _next_wait(wait, ret, jitter, elapsed, max_time_value)
59
65
  except StopIteration:
60
66
  _call_handlers(on_giveup, **details)
61
67
  break
62
68
 
63
- _call_handlers(on_backoff, **details,
64
- value=ret, wait=seconds)
69
+ _call_handlers(on_backoff, **details, value=ret, wait=seconds)
65
70
 
66
71
  time.sleep(seconds)
67
72
  continue
@@ -74,12 +79,21 @@ def retry_predicate(target, wait_gen, predicate,
74
79
  return retry
75
80
 
76
81
 
77
- def retry_exception(target, wait_gen, exception,
78
- *,
79
- max_tries, max_time, jitter, giveup,
80
- on_success, on_backoff, on_giveup, raise_on_giveup,
81
- wait_gen_kwargs):
82
-
82
+ def retry_exception(
83
+ target,
84
+ wait_gen,
85
+ exception,
86
+ *,
87
+ max_tries,
88
+ max_time,
89
+ jitter,
90
+ giveup,
91
+ on_success,
92
+ on_backoff,
93
+ on_giveup,
94
+ raise_on_giveup,
95
+ wait_gen_kwargs,
96
+ ):
83
97
  @functools.wraps(target)
84
98
  def retry(*args, **kwargs):
85
99
  max_tries_value = _maybe_call(max_tries)
@@ -102,9 +116,10 @@ def retry_exception(target, wait_gen, exception,
102
116
  try:
103
117
  ret = target(*args, **kwargs)
104
118
  except exception as e:
105
- max_tries_exceeded = (tries == max_tries_value)
106
- max_time_exceeded = (max_time_value is not None and
107
- elapsed >= max_time_value)
119
+ max_tries_exceeded = tries == max_tries_value
120
+ max_time_exceeded = (
121
+ max_time_value is not None and elapsed >= max_time_value
122
+ )
108
123
 
109
124
  if giveup(e) or max_tries_exceeded or max_time_exceeded:
110
125
  _call_handlers(on_giveup, **details, exception=e)
@@ -113,18 +128,17 @@ def retry_exception(target, wait_gen, exception,
113
128
  return None
114
129
 
115
130
  try:
116
- seconds = _next_wait(wait, e, jitter, elapsed,
117
- max_time_value)
131
+ seconds = _next_wait(wait, e, jitter, elapsed, max_time_value)
118
132
  except StopIteration:
119
133
  _call_handlers(on_giveup, **details, exception=e)
120
134
  raise e
121
135
 
122
- _call_handlers(on_backoff, **details, wait=seconds,
123
- exception=e)
136
+ _call_handlers(on_backoff, **details, wait=seconds, exception=e)
124
137
 
125
138
  time.sleep(seconds)
126
139
  else:
127
140
  _call_handlers(on_success, **details)
128
141
 
129
142
  return ret
143
+
130
144
  return retry
backoff/_typing.py CHANGED
@@ -1,23 +1,21 @@
1
- # coding:utf-8
2
1
  import logging
3
- import sys
4
- from typing import (Any, Callable, Coroutine, Dict, Generator, Sequence, Tuple,
5
- TypeVar, Union)
6
-
7
- if sys.version_info >= (3, 8): # pragma: no cover
8
- from typing import TypedDict
9
- else: # pragma: no cover
10
- # use typing_extensions if installed but don't require it
11
- try:
12
- from typing_extensions import TypedDict
13
- except ImportError:
14
- class TypedDict(dict):
15
- def __init_subclass__(cls, **kwargs: Any) -> None:
16
- return super().__init_subclass__()
2
+ from types import FunctionType
3
+ from typing import (
4
+ Any,
5
+ Callable,
6
+ Coroutine,
7
+ Dict,
8
+ Generator,
9
+ Sequence,
10
+ Tuple,
11
+ TypedDict,
12
+ TypeVar,
13
+ Union,
14
+ )
17
15
 
18
16
 
19
17
  class _Details(TypedDict):
20
- target: Callable[..., Any]
18
+ target: FunctionType
21
19
  args: Tuple[Any, ...]
22
20
  kwargs: Dict[str, Any]
23
21
  tries: int
@@ -32,7 +30,7 @@ class Details(_Details, total=False):
32
30
 
33
31
  T = TypeVar("T")
34
32
 
35
- _CallableT = TypeVar('_CallableT', bound=Callable[..., Any])
33
+ _CallableT = TypeVar("_CallableT", bound=Callable[..., Any])
36
34
  _Handler = Union[
37
35
  Callable[[Details], None],
38
36
  Callable[[Details], Coroutine[Any, Any, None]],
backoff/_wait_gen.py CHANGED
@@ -1,5 +1,3 @@
1
- # coding:utf-8
2
-
3
1
  import itertools
4
2
  import math
5
3
  from typing import Any, Callable, Generator, Iterable, Optional, Union
@@ -10,7 +8,6 @@ def expo(
10
8
  factor: float = 1,
11
9
  max_value: Optional[float] = None,
12
10
  ) -> Generator[float, Any, None]:
13
-
14
11
  """Generator for exponential decay.
15
12
 
16
13
  Args:
@@ -37,7 +34,6 @@ def decay(
37
34
  decay_factor: float = 1,
38
35
  min_value: Optional[float] = None,
39
36
  ) -> Generator[float, Any, None]:
40
-
41
37
  """Generator for exponential decay[1]:
42
38
 
43
39
  Args:
backoff/types.py CHANGED
@@ -1,6 +1,5 @@
1
- # coding:utf-8
2
1
  from ._typing import Details
3
2
 
4
3
  __all__ = [
5
- 'Details',
4
+ "Details",
6
5
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-backoff
3
- Version: 2.3.0
3
+ Version: 2.3.1
4
4
  Summary: Function decoration for backoff and retry
5
5
  Project-URL: Documentation, https://python-backoff.github.io/backoff
6
6
  Project-URL: Repository, https://github.com/python-backoff/backoff
@@ -58,7 +58,7 @@ for asynchronous code.
58
58
  Examples
59
59
  ========
60
60
 
61
- Since Kenneth Reitz's `requests <http://python-requests.org>`_ module
61
+ Since Kenneth Reitz's `requests <https://requests.readthedocs.io>`_ module
62
62
  has become a defacto standard for synchronous HTTP clients in Python,
63
63
  networking examples below are written using it, but it is in no way required
64
64
  by the backoff module.
@@ -72,8 +72,10 @@ is raised. Here's an example using exponential backoff when any
72
72
 
73
73
  .. code-block:: python
74
74
 
75
- @backoff.on_exception(backoff.expo,
76
- requests.exceptions.RequestException)
75
+ @backoff.on_exception(
76
+ backoff.expo,
77
+ requests.exceptions.RequestException,
78
+ )
77
79
  def get_url(url):
78
80
  return requests.get(url)
79
81
 
@@ -82,9 +84,13 @@ the same backoff behavior is desired for more than one exception type:
82
84
 
83
85
  .. code-block:: python
84
86
 
85
- @backoff.on_exception(backoff.expo,
86
- (requests.exceptions.Timeout,
87
- requests.exceptions.ConnectionError))
87
+ @backoff.on_exception(
88
+ backoff.expo,
89
+ (
90
+ requests.exceptions.Timeout,
91
+ requests.exceptions.ConnectionError,
92
+ ),
93
+ )
88
94
  def get_url(url):
89
95
  return requests.get(url)
90
96
 
@@ -98,9 +104,11 @@ of total time in seconds that can elapse before giving up.
98
104
 
99
105
  .. code-block:: python
100
106
 
101
- @backoff.on_exception(backoff.expo,
102
- requests.exceptions.RequestException,
103
- max_time=60)
107
+ @backoff.on_exception(
108
+ backoff.expo,
109
+ requests.exceptions.RequestException,
110
+ max_time=60,
111
+ )
104
112
  def get_url(url):
105
113
  return requests.get(url)
106
114
 
@@ -110,10 +118,12 @@ to make to the target function before giving up.
110
118
 
111
119
  .. code-block:: python
112
120
 
113
- @backoff.on_exception(backoff.expo,
114
- requests.exceptions.RequestException,
115
- max_tries=8,
116
- jitter=None)
121
+ @backoff.on_exception(
122
+ backoff.expo,
123
+ requests.exceptions.RequestException,
124
+ max_tries=8,
125
+ jitter=None,
126
+ )
117
127
  def get_url(url):
118
128
  return requests.get(url)
119
129
 
@@ -129,10 +139,13 @@ be retried:
129
139
  def fatal_code(e):
130
140
  return 400 <= e.response.status_code < 500
131
141
 
132
- @backoff.on_exception(backoff.expo,
133
- requests.exceptions.RequestException,
134
- max_time=300,
135
- giveup=fatal_code)
142
+
143
+ @backoff.on_exception(
144
+ backoff.expo,
145
+ requests.exceptions.RequestException,
146
+ max_time=300,
147
+ giveup=fatal_code,
148
+ )
136
149
  def get_url(url):
137
150
  return requests.get(url)
138
151
 
@@ -150,11 +163,14 @@ case, regardless of the logic in the `on_exception` handler.
150
163
  def fatal_code(e):
151
164
  return 400 <= e.response.status_code < 500
152
165
 
153
- @backoff.on_exception(backoff.expo,
154
- requests.exceptions.RequestException,
155
- max_time=300,
156
- raise_on_giveup=False,
157
- giveup=fatal_code)
166
+
167
+ @backoff.on_exception(
168
+ backoff.expo,
169
+ requests.exceptions.RequestException,
170
+ max_time=300,
171
+ raise_on_giveup=False,
172
+ giveup=fatal_code,
173
+ )
158
174
  def get_url(url):
159
175
  return requests.get(url)
160
176
 
@@ -174,7 +190,11 @@ return value of the target function is the empty list:
174
190
 
175
191
  .. code-block:: python
176
192
 
177
- @backoff.on_predicate(backoff.fibo, lambda x: x == [], max_value=13)
193
+ @backoff.on_predicate(
194
+ backoff.fibo,
195
+ lambda x: x == [],
196
+ max_value=13,
197
+ )
178
198
  def poll_for_messages(queue):
179
199
  return queue.get()
180
200
 
@@ -196,7 +216,11 @@ gets a non-falsey result could be defined like like this:
196
216
 
197
217
  .. code-block:: python
198
218
 
199
- @backoff.on_predicate(backoff.constant, jitter=None, interval=1)
219
+ @backoff.on_predicate(
220
+ backoff.constant,
221
+ jitter=None,
222
+ interval=1,
223
+ )
200
224
  def poll_for_message(queue):
201
225
  return queue.get()
202
226
 
@@ -249,12 +273,16 @@ backoff behavior for different cases:
249
273
  .. code-block:: python
250
274
 
251
275
  @backoff.on_predicate(backoff.fibo, max_value=13)
252
- @backoff.on_exception(backoff.expo,
253
- requests.exceptions.HTTPError,
254
- max_time=60)
255
- @backoff.on_exception(backoff.expo,
256
- requests.exceptions.Timeout,
257
- max_time=300)
276
+ @backoff.on_exception(
277
+ backoff.expo,
278
+ requests.exceptions.HTTPError,
279
+ max_time=60,
280
+ )
281
+ @backoff.on_exception(
282
+ backoff.expo,
283
+ requests.exceptions.Timeout,
284
+ max_time=300,
285
+ )
258
286
  def poll_for_message(queue):
259
287
  return queue.get()
260
288
 
@@ -277,9 +305,13 @@ runtime to obtain the value:
277
305
  # and that it has a dictionary-like 'config' property
278
306
  return app.config["BACKOFF_MAX_TIME"]
279
307
 
280
- @backoff.on_exception(backoff.expo,
281
- ValueError,
282
- max_time=lookup_max_time)
308
+
309
+ @backoff.on_exception(
310
+ backoff.expo,
311
+ ValueError,
312
+ max_time=lookup_max_time,
313
+ )
314
+ def my_function(): ...
283
315
 
284
316
  Event handlers
285
317
  --------------
@@ -307,13 +339,18 @@ implemented like so:
307
339
  .. code-block:: python
308
340
 
309
341
  def backoff_hdlr(details):
310
- print ("Backing off {wait:0.1f} seconds after {tries} tries "
311
- "calling function {target} with args {args} and kwargs "
312
- "{kwargs}".format(**details))
342
+ print(
343
+ "Backing off {wait:0.1f} seconds after {tries} tries "
344
+ "calling function {target} with args {args} and kwargs "
345
+ "{kwargs}".format(**details)
346
+ )
347
+
313
348
 
314
- @backoff.on_exception(backoff.expo,
315
- requests.exceptions.RequestException,
316
- on_backoff=backoff_hdlr)
349
+ @backoff.on_exception(
350
+ backoff.expo,
351
+ requests.exceptions.RequestException,
352
+ on_backoff=backoff_hdlr,
353
+ )
317
354
  def get_url(url):
318
355
  return requests.get(url)
319
356
 
@@ -325,9 +362,14 @@ handler functions as the value of the ``on_backoff`` keyword arg:
325
362
 
326
363
  .. code-block:: python
327
364
 
328
- @backoff.on_exception(backoff.expo,
329
- requests.exceptions.RequestException,
330
- on_backoff=[backoff_hdlr1, backoff_hdlr2])
365
+ @backoff.on_exception(
366
+ backoff.expo,
367
+ requests.exceptions.RequestException,
368
+ on_backoff=[
369
+ backoff_hdlr1,
370
+ backoff_hdlr2,
371
+ ],
372
+ )
331
373
  def get_url(url):
332
374
  return requests.get(url)
333
375
 
@@ -358,9 +400,13 @@ asynchronous HTTP client/server library.
358
400
 
359
401
  .. code-block:: python
360
402
 
361
- @backoff.on_exception(backoff.expo, aiohttp.ClientError, max_time=60)
403
+ @backoff.on_exception(
404
+ backoff.expo,
405
+ aiohttp.ClientError,
406
+ max_time=60,
407
+ )
362
408
  async def get_url(url):
363
- async with aiohttp.ClientSession(raise_for_status=True) as session:
409
+ async with aiohttp.ClientSession(raise_for_status=True) as session: # noqa: SIM117
364
410
  async with session.get(url) as response:
365
411
  return await response.text()
366
412
 
@@ -375,7 +421,7 @@ as:
375
421
 
376
422
  .. code-block:: python
377
423
 
378
- logging.getLogger('backoff').addHandler(logging.StreamHandler())
424
+ logging.getLogger("backoff").addHandler(logging.StreamHandler())
379
425
 
380
426
  The default logging level is INFO, which corresponds to logging
381
427
  anytime a retry event occurs. If you would instead like to log
@@ -383,7 +429,7 @@ only when a giveup event occurs, set the logger level to ERROR.
383
429
 
384
430
  .. code-block:: python
385
431
 
386
- logging.getLogger('backoff').setLevel(logging.ERROR)
432
+ logging.getLogger("backoff").setLevel(logging.ERROR)
387
433
 
388
434
  It is also possible to specify an alternate logger with the ``logger``
389
435
  keyword argument. If a string value is specified the logger will be
@@ -391,25 +437,30 @@ looked up by name.
391
437
 
392
438
  .. code-block:: python
393
439
 
394
- @backoff.on_exception(backoff.expo,
395
- requests.exceptions.RequestException,
396
- logger='my_logger')
397
- # ...
440
+ @backoff.on_exception(
441
+ backoff.expo,
442
+ requests.exceptions.RequestException,
443
+ logger="my_logger",
444
+ )
445
+ def my_function(): ...
398
446
 
399
447
  It is also supported to specify a Logger (or LoggerAdapter) object
400
448
  directly.
401
449
 
402
450
  .. code-block:: python
403
451
 
404
- my_logger = logging.getLogger('my_logger')
452
+ my_logger = logging.getLogger("my_logger")
405
453
  my_handler = logging.StreamHandler()
406
454
  my_logger.addHandler(my_handler)
407
455
  my_logger.setLevel(logging.ERROR)
408
456
 
409
- @backoff.on_exception(backoff.expo,
410
- requests.exceptions.RequestException,
411
- logger=my_logger)
412
- # ...
457
+
458
+ @backoff.on_exception(
459
+ backoff.expo,
460
+ requests.exceptions.RequestException,
461
+ logger=my_logger,
462
+ )
463
+ def my_function(): ...
413
464
 
414
465
  Default logging can be disabled all together by specifying
415
466
  ``logger=None``. In this case, if desired alternative logging behavior
@@ -0,0 +1,14 @@
1
+ backoff/__init__.py,sha256=MS4ieVYpjBh-feDqzJHYJy8mjnuEEaprTWWuXgJI-1A,914
2
+ backoff/_async.py,sha256=Ehv3H3jMF9JylzZzHTLSLwK_s0PoJa_1jeGo3qtpcOY,6370
3
+ backoff/_common.py,sha256=Q8ZB8mCMI76WLii8JcrfoSZc11WRqu7ci_mpG1y-j9Y,3460
4
+ backoff/_decorator.py,sha256=61iXFb5jN2mQ9-1mtRPi_gysJwuyhkKrbDVNWH8GDxo,9483
5
+ backoff/_jitter.py,sha256=wzQHBDNuYg7owbc3fcZLOr5uhhRgqiuncU5rIYOB9lY,766
6
+ backoff/_sync.py,sha256=7W0aTlntrL237rfhy2yaFklZheQoYxBTD5F_4TUarQI,3867
7
+ backoff/_typing.py,sha256=hO065un_HjJEsEa_OgW66JZRyxVf-BsJ9HrswIwW3fA,1056
8
+ backoff/_wait_gen.py,sha256=ZTZfs4WiI295EvOJeJYPIUAABQ0WBAKcvUtg0_ZId8k,3244
9
+ backoff/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ backoff/types.py,sha256=rOQAfuetqVwfEIuzVvK5D_w97A3wrZ9lQ8HwuJ_uq5s,59
11
+ python_backoff-2.3.1.dist-info/METADATA,sha256=o7ltpQ3fk4s05tUCVIeUgZVzGFfigmw06jNoz6HM6RI,14885
12
+ python_backoff-2.3.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
13
+ python_backoff-2.3.1.dist-info/licenses/LICENSE,sha256=KmtNX4hNTXob8E6n3xlEzxKzLjWnmobQoHWi0_QPuaw,1077
14
+ python_backoff-2.3.1.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- backoff/__init__.py,sha256=cxmsrw6PUsF2VsUnaX-gyKsJ5If3iKVIKoVU5Fg2njc,928
2
- backoff/_async.py,sha256=e09CDHH3x16oCS5SEi8RRK9DIyBqGT5pK1JE80awIqk,6675
3
- backoff/_common.py,sha256=cz5AKeSyFxjZ5-g9YK_MB_u1yRt3N3x81EbMZGz7inI,3480
4
- backoff/_decorator.py,sha256=EKqIQ6Igv2sNGAYhZlqsWGHyvu90AE9HQvTj8joXJA8,9820
5
- backoff/_jitter.py,sha256=LjJShpjryk9sWBCWiz-3UX1DJCx6rebNJ5Bf3nPMlYQ,782
6
- backoff/_sync.py,sha256=2Klcl79pg7AeX6h6j0Pnt-Cfx0w3CftgiMSPRPq6TL4,4089
7
- backoff/_typing.py,sha256=K4xjbkoQUuKt5E1cEAUgIPrhrV2lWD3BXmgu8_Mv7rQ,1422
8
- backoff/_wait_gen.py,sha256=aPTQQHmi9k_XpOUsuSoGyW-EpEOwUErLfG_IbNXmaY0,3262
9
- backoff/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- backoff/types.py,sha256=fPaXJ_J81Bme-F2-RKeVDjB3Rvfnj9K4tumDDS03bNs,74
11
- python_backoff-2.3.0.dist-info/METADATA,sha256=RjKF4ttvWjzuy-7IPMhbevvS92tpeyu-woDJs3IOMMs,14910
12
- python_backoff-2.3.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
13
- python_backoff-2.3.0.dist-info/licenses/LICENSE,sha256=KmtNX4hNTXob8E6n3xlEzxKzLjWnmobQoHWi0_QPuaw,1077
14
- python_backoff-2.3.0.dist-info/RECORD,,