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.