-
Notifications
You must be signed in to change notification settings - Fork 40
Description
I am writing a somewhat complex application that uses metaclasses to decorate functions (specifically, add views for a pyramid web application). However, when decorating inside a metaclass, venusian breaks.
From looking at the source, the reason for this seems to be the detection of scope that assumes I must be in a function call (which is correct) and therefore am not decorating a class method (which is incorrect).
I have never worked with venusian before but I tried to figure out the source code anyway. However, at this point I had to give up: I don't exactly understand what's going on here, so I couldn't figure out a fix. Instead, I have created a small testcase that replicates this issue:
import venusian
def test_decorator(wrapped):
print("Decorated")
def _callback(context, name, ob):
print("Callback called")
venusian.attach(wrapped, _callback)
return test_decorator
class TestMeta(type):
def __init__(self, name, bases, attrs):
self.test = test_decorator(self.test)
class Test:
__metaclass__ = TestMeta
#@test_decorator
def test(self):
print("test called")
This is, in essence, the problem: The decoration happens during the TestMeta.__init__ method (thus it is a function call) but the method being decorated is at the class scope.
I have tried playing with the depth parameter but I cannot get it to a class level (likely because of the way metaclasses work). If this is not considered a bug, please let me know how to work around it.
Note: You can check the correct way by removing the comment for the decorator above test and commeting out the __metaclass__ attribute instead:
class Test:
#__metaclass__ = TestMeta
@test_decorator
def test(self):
print("test called")