def retries(max_tries, exceptions=(Exception,)):
def decorator(func):<EOL><INDENT>def function(*args, **kwargs):<EOL><INDENT>retries_left = max_tries<EOL>while retries_left > <NUM_LIT:0>:<EOL><INDENT>try:<EOL><INDENT>retries_left -= <NUM_LIT:1><EOL>return func(*args, **kwargs)<EOL><DEDENT>except exceptions as exc:<EOL><INDENT>if isinstance(exc, PandoraException):<EOL><INDENT>raise<EOL><DEDENT>if retries_left > <NUM_LIT:0>:<EOL><INDENT>time.sleep(delay_exponential(<EOL><NUM_LIT:0.5>, <NUM_LIT:2>, max_tries - retries_left))<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return function<EOL><DEDENT>return decorator<EOL>
Function decorator implementing retrying logic.

    exceptions: A tuple of exception classes; default (Exception,)

    The decorator will call the function up to max_tries times if it raises
    an exception.

    By default it catches instances of the Exception class and subclasses.
    This will recover after all but the most fatal errors. You may specify a
    custom tuple of exception classes with the 'exceptions' argument; the
    function will only be retried if it raises one of the specified
    exceptions.