| 189 | min_passes = 1 |
| 190 | |
| 191 | def decorator(target_func): |
| 192 | @wraps(target_func) |
| 193 | def wrapper(*args, **kwargs): |
| 194 | passes = 0 |
| 195 | for i in range(max_runs): |
| 196 | try: |
| 197 | result = target_func(*args, **kwargs) |
| 198 | passes += 1 |
| 199 | if passes == min_passes: |
| 200 | return result |
| 201 | except Exception as e: |
| 202 | if i == max_runs - 1: |
| 203 | raise e |
| 204 | print( |
| 205 | f"Retrying after attempt {i+1} of {func_name or target_func.__name__} failed with ({reason})):\n" |
| 206 | f"{traceback.format_exc()}", |
| 207 | file=sys.stderr, |
| 208 | ) |
| 209 | time.sleep(delay) |
| 210 | if reset_func: |
| 211 | reset_func() |
| 212 | |
| 213 | return wrapper |
| 214 | |
| 215 | return decorator |
| 216 | |