human
I wrote the below code

    if (fail_classes and retry_classes and set(fail_classes).intersection(retry_classes)):
        raise ValueError("Can't    include    exception    classes    in    both    fail_on    and    retry_on")
    def should_retry_on(exc):
        if (fail_classes and isinstance(exc, tuple(fail_classes))):
            return False
        if (retry_classes and (not isinstance(exc, tuple(retry_classes)))):
            return False
        return True
    @functools.wraps(func)
    def wrapped(*args, **kwargs):
        while True:
            try:
                return func(*args, **kwargs)
            except gevent.GreenletExit as e:
                raise
            except Exception as e:
                if (not should_retry_on(e)):
                    raise
                if (exc_callback is not None):
                    exc_callback(e)
            gevent.sleep((backoff_delay + int(random.uniform(1, 10))))
    return wrapped

What's a good function header?
 ... Here's a good function header?
assistant
#Here's a good function header.

def retry(func, retry_classes=None, fail_classes=None, exc_callback=None, backoff_delay=BACKOFF_DELAY):