backon 3.2.0__tar.gz → 3.4.0__tar.gz
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.
- {backon-3.2.0 → backon-3.4.0}/PKG-INFO +1 -1
- {backon-3.2.0 → backon-3.4.0}/backon/__init__.py +2 -1
- {backon-3.2.0 → backon-3.4.0}/backon/_common.py +10 -15
- {backon-3.2.0 → backon-3.4.0}/backon/_decorator.py +23 -5
- {backon-3.2.0 → backon-3.4.0}/backon/_retry.py +363 -116
- {backon-3.2.0 → backon-3.4.0}/backon/_state.py +42 -0
- {backon-3.2.0 → backon-3.4.0}/pyproject.toml +1 -1
- {backon-3.2.0 → backon-3.4.0}/tests/test_backon.py +1 -0
- backon-3.4.0/tests/test_retry_call_state.py +292 -0
- {backon-3.2.0 → backon-3.4.0}/LICENSE +0 -0
- {backon-3.2.0 → backon-3.4.0}/README.md +0 -0
- {backon-3.2.0 → backon-3.4.0}/backon/_async.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/backon/_conditions.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/backon/_jitter.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/backon/_sync.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/backon/_typing.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/backon/_wait_gen.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/backon/py.typed +0 -0
- {backon-3.2.0 → backon-3.4.0}/backon/types.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/tests/__init__.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/tests/test_advanced_features.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/tests/test_backon_async.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/tests/test_backon_predicate.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/tests/test_backon_sync.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/tests/test_features.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/tests/test_jitter.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/tests/test_retry.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/tests/test_types.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/tests/test_typing.py +0 -0
- {backon-3.2.0 → backon-3.4.0}/tests/test_wait_gen.py +0 -0
|
@@ -25,7 +25,7 @@ from backon._conditions import (
|
|
|
25
25
|
from backon._decorator import on_exception, on_predicate
|
|
26
26
|
from backon._jitter import full_jitter, random_jitter
|
|
27
27
|
from backon._retry import Retrying, retry, sleep_using_event
|
|
28
|
-
from backon._state import RetryError, RetryState, TryAgain
|
|
28
|
+
from backon._state import RetryCallState, RetryError, RetryState, TryAgain
|
|
29
29
|
from backon._wait_gen import (
|
|
30
30
|
constant,
|
|
31
31
|
decay,
|
|
@@ -66,6 +66,7 @@ __all__ = [
|
|
|
66
66
|
"TryAgain",
|
|
67
67
|
"RetryError",
|
|
68
68
|
"RetryState",
|
|
69
|
+
"RetryCallState",
|
|
69
70
|
"Stop",
|
|
70
71
|
"RetryCondition",
|
|
71
72
|
"stop_after_attempt",
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import logging
|
|
3
|
-
import sys
|
|
4
3
|
import time as time_module
|
|
5
|
-
import traceback
|
|
6
4
|
|
|
7
5
|
_logger = logging.getLogger("backon")
|
|
8
6
|
_logger.addHandler(logging.NullHandler())
|
|
@@ -63,6 +61,8 @@ def _prepare_logger(logger):
|
|
|
63
61
|
def _config_handlers(
|
|
64
62
|
user_handlers, *, default_handler=None, logger=None, log_level=None
|
|
65
63
|
):
|
|
64
|
+
if isinstance(user_handlers, list) and logger is None:
|
|
65
|
+
return user_handlers
|
|
66
66
|
handlers = []
|
|
67
67
|
if logger is not None:
|
|
68
68
|
assert log_level is not None
|
|
@@ -84,28 +84,23 @@ def _config_handlers(
|
|
|
84
84
|
|
|
85
85
|
def _log_backoff(details, logger, log_level):
|
|
86
86
|
msg = "Backing off %s(...) for %.1fs (%s)"
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
exc_typ, exc, _ = sys.exc_info()
|
|
87
|
+
exc = details.get("exception")
|
|
90
88
|
if exc is not None:
|
|
91
|
-
exc_fmt =
|
|
92
|
-
log_args.append(exc_fmt.rstrip("\n"))
|
|
89
|
+
exc_fmt = f"{type(exc).__name__}: {exc}"
|
|
93
90
|
else:
|
|
94
|
-
|
|
91
|
+
exc_fmt = details.get("value", "unknown")
|
|
92
|
+
log_args = [details["target"].__name__, details["wait"], exc_fmt]
|
|
95
93
|
logger.log(log_level, msg, *log_args)
|
|
96
94
|
|
|
97
95
|
|
|
98
96
|
def _log_giveup(details, logger, log_level):
|
|
99
97
|
msg = "Giving up %s(...) after %d tries (%s)"
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
exc_typ, exc, _ = sys.exc_info()
|
|
98
|
+
exc = details.get("exception")
|
|
103
99
|
if exc is not None:
|
|
104
|
-
exc_fmt =
|
|
105
|
-
log_args.append(exc_fmt.rstrip("\n"))
|
|
100
|
+
exc_fmt = f"{type(exc).__name__}: {exc}"
|
|
106
101
|
else:
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
exc_fmt = details.get("value", "unknown")
|
|
103
|
+
log_args = [details["target"].__name__, details["tries"], exc_fmt]
|
|
109
104
|
logger.log(log_level, msg, *log_args)
|
|
110
105
|
|
|
111
106
|
|
|
@@ -21,7 +21,7 @@ from backon._conditions import (
|
|
|
21
21
|
retry_if_result,
|
|
22
22
|
)
|
|
23
23
|
from backon._jitter import full_jitter
|
|
24
|
-
from backon._retry import
|
|
24
|
+
from backon._retry import _retry_async_inner, _retry_sync_inner
|
|
25
25
|
from backon._state import RetryState
|
|
26
26
|
from backon._typing import (
|
|
27
27
|
P,
|
|
@@ -54,10 +54,13 @@ def on_predicate(
|
|
|
54
54
|
retry_error_callback: Callable[[dict], Any] | None = None,
|
|
55
55
|
raise_on_giveup: bool = True,
|
|
56
56
|
sleep: Callable[[float], Any] | None = None,
|
|
57
|
+
before: _Handler | Iterable[_Handler] | None = None,
|
|
58
|
+
after: _Handler | Iterable[_Handler] | None = None,
|
|
57
59
|
**wait_gen_kwargs: Any,
|
|
58
60
|
) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
59
61
|
def decorate(target: Callable[P, R]) -> Callable[P, R]:
|
|
60
62
|
nonlocal logger, on_success, on_backoff, on_giveup, on_attempt, before_sleep
|
|
63
|
+
nonlocal before, after
|
|
61
64
|
|
|
62
65
|
logger = _prepare_logger(logger)
|
|
63
66
|
on_success = _config_handlers(on_success)
|
|
@@ -75,6 +78,8 @@ def on_predicate(
|
|
|
75
78
|
)
|
|
76
79
|
on_attempt = _config_handlers(on_attempt)
|
|
77
80
|
before_sleep = _config_handlers(before_sleep)
|
|
81
|
+
before = _config_handlers(before)
|
|
82
|
+
after = _config_handlers(after)
|
|
78
83
|
|
|
79
84
|
condition: RetryCondition = retry_if_result(predicate)
|
|
80
85
|
|
|
@@ -91,7 +96,7 @@ def on_predicate(
|
|
|
91
96
|
|
|
92
97
|
return cast(
|
|
93
98
|
R,
|
|
94
|
-
await
|
|
99
|
+
await _retry_async_inner(
|
|
95
100
|
wrapped,
|
|
96
101
|
wait_gen,
|
|
97
102
|
condition=condition,
|
|
@@ -107,6 +112,8 @@ def on_predicate(
|
|
|
107
112
|
retry_error_callback=retry_error_callback,
|
|
108
113
|
raise_on_giveup=raise_on_giveup,
|
|
109
114
|
wait_gen_kwargs=wait_gen_kwargs,
|
|
115
|
+
before=before,
|
|
116
|
+
after=after,
|
|
110
117
|
),
|
|
111
118
|
)
|
|
112
119
|
|
|
@@ -121,7 +128,7 @@ def on_predicate(
|
|
|
121
128
|
|
|
122
129
|
return cast(
|
|
123
130
|
R,
|
|
124
|
-
|
|
131
|
+
_retry_sync_inner(
|
|
125
132
|
lambda: target(*args, **kwargs),
|
|
126
133
|
wait_gen,
|
|
127
134
|
condition=condition,
|
|
@@ -137,6 +144,8 @@ def on_predicate(
|
|
|
137
144
|
retry_error_callback=retry_error_callback,
|
|
138
145
|
raise_on_giveup=raise_on_giveup,
|
|
139
146
|
wait_gen_kwargs=wait_gen_kwargs,
|
|
147
|
+
before=before,
|
|
148
|
+
after=after,
|
|
140
149
|
),
|
|
141
150
|
)
|
|
142
151
|
|
|
@@ -164,10 +173,13 @@ def on_exception(
|
|
|
164
173
|
backoff_log_level: int = logging.INFO,
|
|
165
174
|
giveup_log_level: int = logging.ERROR,
|
|
166
175
|
sleep: Callable[[float], Any] | None = None,
|
|
176
|
+
before: _Handler | Iterable[_Handler] | None = None,
|
|
177
|
+
after: _Handler | Iterable[_Handler] | None = None,
|
|
167
178
|
**wait_gen_kwargs: Any,
|
|
168
179
|
) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
169
180
|
def decorate(target: Callable[P, R]) -> Callable[P, R]:
|
|
170
181
|
nonlocal logger, on_success, on_backoff, on_giveup, on_attempt, before_sleep
|
|
182
|
+
nonlocal before, after
|
|
171
183
|
|
|
172
184
|
logger = _prepare_logger(logger)
|
|
173
185
|
on_success = _config_handlers(on_success)
|
|
@@ -185,6 +197,8 @@ def on_exception(
|
|
|
185
197
|
)
|
|
186
198
|
on_attempt = _config_handlers(on_attempt)
|
|
187
199
|
before_sleep = _config_handlers(before_sleep)
|
|
200
|
+
before = _config_handlers(before)
|
|
201
|
+
after = _config_handlers(after)
|
|
188
202
|
|
|
189
203
|
exc_types: tuple[type[Exception], ...]
|
|
190
204
|
if isinstance(exception, type):
|
|
@@ -217,7 +231,7 @@ def on_exception(
|
|
|
217
231
|
|
|
218
232
|
return cast(
|
|
219
233
|
R,
|
|
220
|
-
await
|
|
234
|
+
await _retry_async_inner(
|
|
221
235
|
wrapped,
|
|
222
236
|
wait_gen,
|
|
223
237
|
condition=condition,
|
|
@@ -233,6 +247,8 @@ def on_exception(
|
|
|
233
247
|
retry_error_callback=retry_error_callback,
|
|
234
248
|
raise_on_giveup=raise_on_giveup,
|
|
235
249
|
wait_gen_kwargs=wait_gen_kwargs,
|
|
250
|
+
before=before,
|
|
251
|
+
after=after,
|
|
236
252
|
),
|
|
237
253
|
)
|
|
238
254
|
|
|
@@ -247,7 +263,7 @@ def on_exception(
|
|
|
247
263
|
|
|
248
264
|
return cast(
|
|
249
265
|
R,
|
|
250
|
-
|
|
266
|
+
_retry_sync_inner(
|
|
251
267
|
lambda: target(*args, **kwargs),
|
|
252
268
|
wait_gen,
|
|
253
269
|
condition=condition,
|
|
@@ -263,6 +279,8 @@ def on_exception(
|
|
|
263
279
|
retry_error_callback=retry_error_callback,
|
|
264
280
|
raise_on_giveup=raise_on_giveup,
|
|
265
281
|
wait_gen_kwargs=wait_gen_kwargs,
|
|
282
|
+
before=before,
|
|
283
|
+
after=after,
|
|
266
284
|
),
|
|
267
285
|
)
|
|
268
286
|
|