2

I was writing a metaclass to force docstring for class and instance method. Well to my surprise staticmethod and classmethod are not callable just like instance method. I am not sure why?

class MyMeta(type):
    def __new__(cls, name, parents, attrs):
        print(cls, name, parents, attrs)

        if "__doc__" not in attrs:
            raise TypeError("Please define class level doc string!!!")

        for key, value in attrs.items():
            if callable(value) and value.__doc__ is None:
                raise TypeError("Please define def level doc string!!!")

        return super().__new__(cls, name, parents, attrs)

class A(metaclass=MyMeta):
    """This is API doc string"""
    def hello(self):
        """"""
        pass

    def __init__(self):
        """__init__ Method"""
        pass

    @classmethod
    def abc(cls):
        pass

I am not able to understand why are they not callable? They seems to pass my check if I don't define docstring for them.

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
Pravin
  • 677
  • 2
  • 7
  • 22

1 Answers1

2

They are not callable. classmethod and staticmethod are descriptor objects, and they do not implement __call__. The HOWTO actually gives examples of how you might implement them in pure python, so for example classmethod objects:

class ClassMethod(object):
    "Emulate PyClassMethod_Type() in Objects/funcobject.c"

    def __init__(self, f):
        self.f = f

    def __get__(self, obj, klass=None):
        if klass is None:
            klass = type(obj)
        def newfunc(*args):
            return self.f(klass, *args)
        return newfunc

Note, function objects are descriptors too. They just happen to be callable descriptors.

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172