Skip to content

Metaclass decoration breaks venusian scope/frame detection mechanism #32

@Javex

Description

@Javex

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")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions