Losing variable scope inside a Python decorator -


this simple decorator works expected:

def protect(*permissions):     def outer(f):         def inner(*args):             print permissions[0]             return f(*args)           return inner       return outer  @protect('protected') def func(var):     return var  print func('something') 

the output is:

protected 

moving beyond python shell , using decorator in larger scope of project, strange happening: while inside of inner function, permissions not defined.

i'm thinking there must python variable scoping/decorator subtleties i'm unaware of causing this. insights appreciated.

in mind figure out going on - let me try spell out:

it has python not "perceiving" "permissions" variable existing on scopes outside "inner" function - since when "inner" defined, "permissions" long have been defined in 'outsidemost' scope of protect. thus, when compiling inner variale taken being global variable. (that why exact error message needed - nameerrors can local variables used before definition, or non-existing global variables - exact message tell in case)

in other words, likley have hit implementation bug - please try expose minimum ammount of code causes issue , exact python version using. if possible try latest micro version available - , ten time open issue @ bugs.python.org

i see 2 workarounds -- first 1 hack confirm diagnosis - , might not work @ all: make reading access permissions variable on outer function, outside inner's body: should make interpretor "perceive" non-local variable in outer, , propagate inner.

the other workaround more solid , consistent - , maybe better code-styling yu in case: use class decorator in case, instead of relying on multiple nested functions , closures.

the above snippet 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 not rely on nested closures, avoidnign bug you've hit. besides, follows "flat better nested" , "explict better implicit" coding guidelines.

but please, trace bug, giving version , code triggers behavior, if not opening issue @ python.org


Comments

Popular posts from this blog

linux - Mailx and Gmail nss config dir -

c# - Is it possible to remove an existing registration from Autofac container builder? -

php - Mysql PK and FK char(36) vs int(10) -