Doctests and decorated methods don't get along

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sat Feb 6 18:03:25 EST 2010


On Sat, 06 Feb 2010 14:00:28 -0500, John Posner wrote:

> On 2/6/2010 6:48 AM, Steven D'Aprano wrote:
>> class MyStaticMethod(object):
>>      """Emulate built-in staticmethod descriptor.""" 
>>      def __init__(self, f):
>>          self.f = f
>>      def __get__(self, obj, objtype=None):
>>          return self.f
> 
> How about using a function, instead of a class, to implement the
> decorator:

I've had problems with function decorators and doctest in the past. If I 
remember the problem correctly, functools.wraps changing the __module__ 
of the wrapped function, making it look like it came from the functool 
module, and so doctest would not run the tests. But it seems that has 
been fixed in 2.6: I can confirm your version works as expected.

Nevertheless, I think it is a limitation of doctest that it doesn't see 
methods using the descriptor protocol. Even if I could work around my 
immediate issue by using a function decorator (and I don't think I can) 
I'd still want to fix this problem.


> I tried making the class-based implementation work by using
> functools.wraps(), but I couldn't manage it. 

Me neither. I think the problem is that the doctest.DocTestFinder class 
doesn't find descriptor-based methods. It special cases staticmethod, 
classmethod and property.



> Also, doesn't the decorator
> protocol want the class to implement a __call__() method, not a
> __get__() method? Or am I getting hung up (not the first time) at the
> nexus of the descriptor and decorator protocols?

In this case, I'm actually using a descriptor as the decorator.

The descriptor is called at attribute lookup, before the method is 
called. __get__ returns a function, which has a __call__ method, and it 
should all just work.



-- 
Steven



More information about the Python-list mailing list