In my mind I could figure out what is going on - let me try to spell it out:
it has to do with Python not "perceiving" the "permissions" variable as existing on the scopes outside the "inner" function - since when "inner" itself is defined, "permissions" would long have been defined in the 'outsidemost' scope of protect. Thus, when compiling inner the variale is taken as being a global variable. (That is why the exact error message is needed - NameErrors can be for local variables used before definition, or for non-existing global variables - the exact message will tell much in this case)
In other words, you most likley have hit an implementation bug - please try to expose the minimum ammount of code that causes the issue and the exact python version you are using. If possible try with the latest micro version available for you - and ten it will be time to open an issue at bugs.python.org
I see two workarounds -- the first one would be a hack that would confirm my diagnosis - and might not work at all: Make a reading access to the permissions variable on the outer function, outside inner's body: that should make the interpretor "perceive" it as a non-local variable in outer, and propagate it into inner.
The other workaround is more solid and consistent - and maybe even better code-styling for yu in this case: to use a class as the decorator in this case, instead of relying on multiple nested functions and its closures.
The above snippet could be rewritten as:
class Protect(object):
def __init__(self, *permissions):
self.permissions = permissions
def __call__(self, f):
def inner(*args):
print self.permissions[0]
return f(*args)
return inner
@Protect('protected')
def func(var):
return var
print func('something')
This code does not rely on nested closures, thus avoidnign the bug you've hit. Besides, it follows the "flat is better than nested" and "explict is better than implicit" coding guidelines.
But please, help everyone to trace this bug, by giving us your version and code that actually triggers this behavior, if not opening an issue at python.org