def retry(<EOL>exceptions=(Exception,), interval=<NUM_LIT:0>, max_retries=<NUM_LIT:10>, success=None,<EOL>timeout=-<NUM_LIT:1>):
if not exceptions and success is None:<EOL><INDENT>raise TypeError(<EOL>'<STR_LIT>')<EOL><DEDENT>exceptions = exceptions or (_DummyException,)<EOL>_retries_error_msg = ('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>_timeout_error_msg = '<STR_LIT>'<EOL>@decorator<EOL>def wrapper(func, *args, **kwargs):<EOL><INDENT>signal.signal(<EOL>signal.SIGALRM, _timeout(<EOL>_timeout_error_msg.format(timeout, func.__name__)))<EOL>run_func = functools.partial(func, *args, **kwargs)<EOL>logger = logging.getLogger(func.__module__)<EOL>if max_retries < <NUM_LIT:0>:<EOL><INDENT>iterator = itertools.count()<EOL><DEDENT>else:<EOL><INDENT>iterator = range(max_retries)<EOL><DEDENT>if timeout > <NUM_LIT:0>:<EOL><INDENT>signal.alarm(timeout)<EOL><DEDENT>for num, _ in enumerate(iterator, <NUM_LIT:1>):<EOL><INDENT>try:<EOL><INDENT>result = run_func()<EOL>if success is None or success(result):<EOL><INDENT>signal.alarm(<NUM_LIT:0>)<EOL>return result<EOL><DEDENT><DEDENT>except exceptions:<EOL><INDENT>logger.exception(<EOL>'<STR_LIT>'.format(<EOL>func.__name__))<EOL>if num == max_retries:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>logger.warning(<EOL>'<STR_LIT>'.format(<EOL>func.__name__, interval))<EOL>time.sleep(interval)<EOL><DEDENT>else:<EOL><INDENT>raise MaximumRetriesExceeded(<EOL>_retries_error_msg.format(<EOL>max_retries, interval, func.__name__))<EOL><DEDENT><DEDENT>return wrapper<EOL>
Decorator to retry a function 'max_retries' amount of times

    :param tuple exceptions: Exceptions to be caught for retries
    :param int interval: Interval between retries in seconds
    :param int max_retries: Maximum number of retries to have, if
        set to -1 the decorator will loop forever
    :param function success: Function to indicate success criteria
    :param int timeout: Timeout interval in seconds, if -1 will retry forever
    :raises MaximumRetriesExceeded: Maximum number of retries hit without
        reaching the success criteria
    :raises TypeError: Both exceptions and success were left None causing the
        decorator to have no valid exit criteria.

    Example:
        Use it to decorate a function!

        .. sourcecode:: python

            from retry import retry

            @retry(exceptions=(ArithmeticError,), success=lambda x: x > 0)
            def foo(bar):
                if bar < 0:
                    raise ArithmeticError('testing this')
                return bar
            foo(5)
            # Should return 5
            foo(-1)
            # Should raise ArithmeticError
            foo(0)
            # Should raise MaximumRetriesExceeded