Reputation: 113
I want to do logging of MongoEngine Documents in my flask application as described here. But I also want to be able to exclude certain attributes that this document class has.
If I give the apply function of a decorator an additional parameter excludes
the cls parameter is no longer given.
Traceback (most recent call last):
File ".../test.py", line 26, in <module>
@__log_update.apply(excludes=[])
TypeError: apply() missing 1 required positional argument: 'cls'
In the simplified code
def handler(*events):
"""
Signal decorator to allow use of callback functions as class decorators.
"""
def decorator(fn):
def apply(cls, excludes=[]):
for exclude in excludes:
print(exclude)
for event in events:
event.connect(fn, sender=cls)
return cls
fn.apply = apply
return fn
return decorator
@handler()
def __log_update(*args, **kwargs):
pass
@__log_update.apply(excludes=['testString'])
class Test(object):
testString = ''
testInt = 0
But when just using @__log_update.apply
without any parameter, the cls parameter is given and is <class '__main__.Test'>
as it should be.
I need both to do the logging.
Upvotes: 1
Views: 63
Reputation: 92854
That about how decorator works.
When you apply it like so (no matter with or without parameters):
@__log_update.apply()
the result of invocation should be a decorator itself which then applied to the underlying class.
You need an additional layer that will make .apply()
function to return a class decorator:
def handler(*events):
"""
Signal decorator to allow use of callback functions as class decorators.
"""
def decorator(fn):
def apply(excludes=[]):
def class_decor(cls):
for exclude in excludes:
print(exclude)
for event in events:
event.connect(fn, sender=cls)
return cls
return class_decor
fn.apply = apply
return fn
return decorator
@handler()
def __log_update(*args, **kwargs):
pass
@__log_update.apply(excludes=['testString'])
class Test(object):
testString = ''
testInt = 0
Upvotes: 1