I'm working on a decorator that will retry running a function up to N times as follows:
def retry(exceptions, truncate=5, delay=0.25):                                     
      """Retry the decorated function using an exponential backoff strategy.         
      If the function does not complete successfully a TimeoutException is           
      raised."""                                                                     
      def wrapper(func):                                                             
          @wraps(func)                                                               
          def wrapped(*args, **kwargs):                                              
              tries = 0                                                              
              while tries < truncate:                                                
                  try:                                                               
                      return func(*args, **kwargs)                                   
                  except exceptions, e:                                              
                      print "%s, Retrying in %d seconds..." % (str(e), delay)        
                      time.sleep(delay)                                              
>>                    delay += delay                                                 
                      tries += 1                                                     
              else:                                                                  
                  raise TimeoutException()                                           
          return wrapped                                                             
      return wrapper
To me the code looks sensible, but on the line highlighted pyflakes complains, reporting:
W804 local variable 'delay' (defined in enclosing scope on line x) referenced before assignment
This doesn't quite make sense to me. delay has been assigned a value, and I presumably should be able to reference it as a I please. Can someone explain what the error is, and if reasonable, how I can fix it?
                        
This code will actually crash if you try running it. The problem is that in nested scopes like
wrapped(andwrapper), you can read outer variables but not assign to them.This is what the
nonlocalkeyword in 3.x is for (which would makedelayincrease across all "instances" ofwrappedfrom a single call toretry). To replicate this in 2.x, you need to do something likedelay_lst = [delay]and access it asdelay_lst[0].If you want the modifications to be local to
wrapped, just make a new variable and initialize it with the value ofdelay.