def teb_retry(exc=RequestException,<EOL>when=dict(response__status_code=<NUM_LIT>),<EOL>delay='<STR_LIT>',<EOL>max_collisions=MAX_COLLISIONS,<EOL>default_retry=DEFAULT_RETRY):
def wrap(f):<EOL><INDENT>@functools.wraps(f)<EOL>def wrapped_f(*args, **kwargs):<EOL><INDENT>attempt = kwargs.pop('<STR_LIT>', <NUM_LIT:0>)<EOL>try:<EOL><INDENT>return f(*args, **kwargs)<EOL><DEDENT>except exc as e:<EOL><INDENT>if kwargsql.and_(e, **when):<EOL><INDENT>try:<EOL><INDENT>retry_after = kwargsql.get(e, delay)<EOL><DEDENT>except:<EOL><INDENT>retry_after = default_retry<EOL><DEDENT>else:<EOL><INDENT>if retry_after is not None:<EOL><INDENT>retry_after = int(retry_after)<EOL><DEDENT>else:<EOL><INDENT>retry_after = default_retry<EOL><DEDENT><DEDENT>countdown = retry_after + truncated_exponential_backoff(<EOL>retry_after, attempt % max_collisions)<EOL>raise Retry(kwargs=dict(attempt=attempt + <NUM_LIT:1>),<EOL>countdown=countdown)<EOL><DEDENT>else:<EOL><INDENT>raise e.with_traceback(sys.exc_info()[<NUM_LIT:2>]) <EOL><DEDENT><DEDENT><DEDENT>return wrapped_f<EOL><DEDENT>return wrap<EOL>
Decorator catching rate limits exceed events during a crawl task.
    It retries the task later on, following a truncated exponential backoff.