I ve got a following code snippet:
def isolation_level(level): def decorator(fn): def recur(level, *args, **kwargs): if connection.inside_block: if connection.isolation_level < level: raise IsolationLevelError(connection) else: fn(*args, **kwargs) else: connection.enter_block() try: connection.set_isolation_level(level) fn(*args, **kwargs) connection.commit() except IsolationLevelError, e: connection.rollback() recur(e.level, *args, **kwargs) finally: connection.leave_block() def newfn(*args, **kwargs): if level is None: # <<<< ERROR MESSAGE HERE, Unbound local variable `level` if len(args): if hasattr(args[0], isolation_level ): level = args[0].isolation_level elif kwargs.has_key( self ): if hasattr(kwargs[ self ], isolation_level ): level = kwargs.pop( self , 1) if connection.is_dirty(): connection.commit() recur(level, *args, **kwargs) return newfn return decorator
It really doesn t matter what it does, however I post it in its original form, as I was unable to recreate the situation with anything simpler.
The problem is that when I call isolation_level(1)(some_func)(some, args, here) I get Unbound local variable exception in line 21 (marked on the listing). I don t understand why. I tried recreating the same structure of functions and function calls that wouldn t contain all the implementation details to figure out what is wrong. However I don t get the exception message then. For example the following works:
def outer(x=None): def outer2(y): def inner(x, *args, **kwargs): print x print y print args print kwargs def inner2(*args, **kwargs): if x is None: print "I m confused" inner(x, *args, **kwargs) return inner2 return outer2 outer(1)(2)(3, z=4)
Prints:
1 2 (3,) { z : 4}
What am I missing??
EDIT
Ok, so the problem is that in the first version I actually perform an assignment to the variable. Python detects that and therefore assumes the variable is local.