def retry_assertion(timeout_sec, retry_interval_sec=0.1):
 def retry_assertion_decorator(func):
  'Decorator'
  @functools.wraps(func)
  def retry_assertion_wrap(*args, **kwargs):
   'The wrapper'
   num_attempts = 0
   start_time = time.time()
   while True:
    num_attempts += 1
    try:
     result = func(*args, **kwargs)
    except AssertionError:
     now = time.time()
     if (now < start_time):
      start_time = now
     if ((now - start_time) > timeout_sec):
      logging.exception("Exceeded retry timeout of %s sec in %s attempts with func %r. Caller's stack:\n%s", timeout_sec, num_attempts, func, ''.join(traceback.format_stack()))
      raise
     logging.debug('Attempt %s failed; retrying %r in %s sec.', num_attempts, func, retry_interval_sec)
     time.sleep(retry_interval_sec)
    else:
     logging.debug('%r succeeded at attempt %s', func, num_attempts)
     return result
  return retry_assertion_wrap
 return retry_assertion_decorator

def retry_assertion ( timeout_sec , retry_interval_sec = 0.1 ) : def retry_assertion_decorator ( func ) : @ functools . wraps ( func ) def retry_assertion_wrap ( * args , ** kwargs ) : num_attempts = 0 start_time = time . time ( ) while True : num_attempts += 1 try : result = func ( * args , ** kwargs ) except AssertionError : now = time . time ( ) if ( now < start_time ) : start_time = now if ( ( now - start_time ) > timeout_sec ) : logging . exception ( "Exceeded retry timeout of %s sec in %s attempts with func %r. Caller's stack:\n%s" , timeout_sec , num_attempts , func , '' . join ( traceback . format_stack ( ) ) ) raise logging . debug ( 'Attempt %s failed; retrying %r in %s sec.' , num_attempts , func , retry_interval_sec ) time . sleep ( retry_interval_sec ) else : logging . debug ( '%r succeeded at attempt %s' , func , num_attempts ) return result return retry_assertion_wrap return retry_assertion_decorator
creates a decorator that retries the decorated function or method only upon assertionerror exception at the given retry interval not to exceed the overall given timeout .