I just realized that I could just implement __get__ and return types.MethodType , but I really don't understand how this still allows calling an empty_function.
This is because MethodType has a __getattribute__ method that delegates unknown attributes to its im_func :
>>> t.dosomething <bound method Test.? of <__main__.Test object at 0x107639550>> >>> 'empty_function' in dir(t.dosomething) False >>> t.dosomething.__getattribute__ <method-wrapper '__getattribute__' of instancemethod object at 0x109583aa0> >>> t.dosomething.__getattribute__('empty_function') <bound method FunctionFaker.empty_function of <__main__.FunctionFaker object at 0x1095f2510>>
Of course, in the CPython API, C does not accurately reflect the Python level difference between __getattribute__ and __getattr__ , so the way it is really implemented is with custom getattro . You can read the details in the source .
MethodType it just become an attribute of the MethodType instance?
Yes, but only dynamically, providing you with an attribute of the underlying caller.
I do not think that they were specifically intended to include class instances that replace functions with method descriptors. But this support is necessary even for simple cases of attaching attributes to methods. For example, using a stand-alone function, you can use the function attribute for, for example, the memoization cache or lazy-initialize-on-first-call. If MethodType did not delegate access to the attribute to the im_func object, moving such a function to the class would violate it, and the developer would not be able to fix it if he did not know how the descriptors work and rewrote the method in an ugly way.
In fact, prior to 2.3, methods did not even have __dict__ ; as you can see from the source , all attributes except C slots were delegated to im_func (by effectively duplicating the usual mechanism for delegating everything to im_func , but wrap errors). There was some debate about this that you could probably find by searching python-dev archives for Christian Tysmer's message in the pre-2.4 period with the corresponding object (this could be this thread , but I haven't read all this ...) . Starting with version 2.4, methods now perform the usual search mechanism (except for the special case __doc__ ) and pass only im_func if it fails.
And is that a reasonable thing?
This is a bit weird, and it would be easier to add the empty_function attribute to the function object rather than wrapping it in a class ... but I don't think this is too unreasonable. (I assume that you are asking about your code, not about how MethodType and descriptors are implemented.)