<commit_before>from functools import wraps
import asyncio
from concurrent.futures import TimeoutError
from .log import logger


def _default_retry_for_result(result):
    return False


def _default_retry_for_exception(exception):
    return False


def retry(*dargs, **dkwargs):
    if len(dargs) == 1 and callable(dargs[0]):
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                yield from RetryHandler().run(func, *args, **kwargs)
            return wrapper
        return decorator(dargs[0])

    else:
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                yield from RetryHandler(*dargs, **dkwargs).run(func, *args, **kwargs)
            return wrapper

        return decorator


class RetryHandler:
    def __init__(self, should_retry_for_result=_default_retry_for_result,
                 should_retry_for_exception=_default_retry_for_exception,
                 multiplier=2, timeout=None, max_attempts=None, strategy=None):
        self._should_retry_for_result = should_retry_for_result
        self._should_retry_for_exception = should_retry_for_exception
        self._multiplier = multiplier
        self._timeout = timeout
        self._max_attempts = max_attempts
        self._strategy = strategy

    @asyncio.coroutine
    def run(self, func, *args, **kwargs):
        if not asyncio.iscoroutinefunction(func):
            func = asyncio.coroutine(func)
        return (yield from self._run_task(0, func, *args, **kwargs))

    @asyncio.coroutine
    def _run_task(self, attempts_made, func, *args, **kwargs):
        if self._max_attempts is not None and attempts_made > self._max_attempts:
            return
        wait_time = self._get_wait_time(attempts_made)
        logger.info('Retrying %s after %s seconds', func.__name__, wait_time)
        yield from asyncio.sleep(wait_time)
        try:
            if self._timeout is None:
                result = yield from func(*args, **kwargs)
            else:
                try:<commit_msg>Adding doc strings<commit_after>from functools import wraps
import asyncio
from concurrent.futures import TimeoutError
from .log import logger


def _default_retry_for_result(result):
    return False


def _default_retry_for_exception(exception):
    return False


def retry(*dargs, **dkwargs):
    if len(dargs) == 1 and callable(dargs[0]):
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                yield from RetryHandler().run(func, *args, **kwargs)
            return wrapper
        return decorator(dargs[0])

    else:
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                yield from RetryHandler(*dargs, **dkwargs).run(func, *args, **kwargs)
            return wrapper

        return decorator


class RetryHandler:
    def __init__(self, should_retry_for_result=_default_retry_for_result,
                 should_retry_for_exception=_default_retry_for_exception,
                 multiplier=2, timeout=None, max_attempts=None, strategy=None):
        """
        :param should_retry_for_result: A function that is called with argument as result to allow retrial for specific
                                        set of results. Must return a boolean value
        :param should_retry_for_exception: A function that is called if the function to be retried threw an exception
                                           allow retrial for specific set of exceptions. Must return a boolean value
        :param multiplier: Must be an integer value, If defined, the retrial would be exponential with this behind the
                           multiplier
        :param timeout: If defined, the function will be retried if no result was returned in this time.
        :param max_attempts: Max number of attempts to retry
        :param strategy: Must be a list of integers. If defined, retrial would follow this strategy. For ex. if strategy
                         is [1,3,5,8,11], function would be retried at 1, 3, 5, 8, 11, 11, 11, ... seconds
        :return:
        """
        self._should_retry_for_result = should_retry_for_result
        self._should_retry_for_exception = should_retry_for_exception
        self._multiplier = multiplier
        self._timeout = timeout
        self._max_attempts = max_attempts
        self._strategy = strategy

    @asyncio.coroutine
    def run(self, func, *args, **kwargs):
        if not asyncio.iscoroutinefunction(func):
            func = asyncio.coroutine(func)
        return (yield from self._run_task(0, func, *args, **kwargs))

    @asyncio.coroutine
    def _run_task(self, attempts_made, func, *args, **kwargs):
        if self._max_attempts is not None and attempts_made > self._max_attempts:
            return
        wait_time = self._get_wait_time(attempts_made)
        logger.info('Retrying %s after %s seconds', func.__name__, wait_time)
        yield from asyncio.sleep(wait_time)
        try:
            if self._timeout is None:
                result = yield from func(*args, **kwargs)
            else:
                try:
{'fraction_non_alphanumeric': 0.08019230769230769, 'fraction_numerical': 0.005, 'mean_word_length': 2.4558139534883723, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1518203', 'n_tokens_mistral': 1465, 'n_tokens_neox': 1448, 'n_words': 416}