Deviopath › Python

Retry Decorator with Arguments

Hard · Decorators

A decorator with arguments is a function that returns a decorator: @retry(3) first calls retry(3), and the result decorates the function. So you need three levels: retry(times, on) returns decorator(func), which returns wrapper(*args, **kwargs).

Write retry(times, on=(Exception,)):

- call the function up to times times in total

- if it raises an exception whose type is in on, try again. Any other exception propagates immediately.

- if the last attempt fails too, re-raise that exception

- the wrapper has an attempts attribute: how many attempts the most recent call used (also when it ends with an error)

- keep the function name with functools.wraps

The driver run_retry(times, outcomes) is already written. It decorates a fake fetch() with @retry(times, on=(ConnectionError,)). Each attempt uses the next outcome: "down" raises ConnectionError("server timed out"), "bad" raises ValueError("bad response"), and anything else is returned as the result.

Next: Transaction Context Manager