On 2/6/2010 6:48 AM, Steven D'Aprano wrote:
It seems that doctest doesn't discover or execute doctests in methods
which have been decorated.


Here is my test file:

# ======
class MyStaticMethod(object):
     """Emulate built-in staticmethod descriptor."""
     def __init__(self, f):
         self.f = f
     def __get__(self, obj, objtype=None):
         return self.f

class Test(object):
     def method1(self):
         """Doc string

         >>>  print 'x'
         x
         """

     @staticmethod
     def method2():
         """Doc string

         >>>  print 'y'
         y
         """

     @MyStaticMethod
     def method3():
         """Doc string

         >>>  print '***'  # This test should fail.
         z
         """

if __name__ == '__main__':
     import doctest
     doctest.testmod(verbose=True)
# ======


and here is the output using Python 2.6.4:

[st...@sylar python]$ python2.6 test_doctests.py
Trying:
     print 'x'
Expecting:
     x
ok
Trying:
     print 'y'
Expecting:
     y
ok
5 items had no tests:
     __main__
     __main__.MyStaticMethod
     __main__.MyStaticMethod.__get__
     __main__.MyStaticMethod.__init__
     __main__.Test
2 items passed all tests:
    1 tests in __main__.Test.method1
    1 tests in __main__.Test.method2
2 tests in 7 items.
2 passed and 0 failed.
Test passed.


It doesn't even see method3, let alone run the tests.

Method3 is wrapped as an instance of MyStaticMethod and doctest does not see that as function. Even if it did, you would might have to copy the docstring (self.__doc__ = f.__doc__) to have the test run.

Note the following: (3.1)

>>> Test.method3
<function method3 at 0x00F5F7C8>
>>> Test.__dict__['method3']
<__main__.MyStaticMethod object at 0x00F5CDF0>
>>> Test.__dict__['method2']
<staticmethod object at 0x00F5C290>

Doctest has to scan the dict, so it does not see the attribute-lookup result.

This looks like  bug to me. Have I missed anything?

I would call it a limitation as I do not see the doc as promising otherwise. I believe doctest predates the descripter protocol, at least in its current form, so it may not be completely descriptor-aware. You certainly could file a feature request for improved recognition and subsequent calling of __get__. An initial patch would improve chances of action.

> Any workarounds?

Perhaps look at the doctest source to see why staticmethod instances are recognized as functions.

If doctest directly special-cases their recognition, then use the standard nested function approach for decorators, making sure to copy the doc string. Look at functools.wraps.

If doctest recognizes them by some characteristic that you have not emulated, try to improve that.

Terry Jan Reedy


Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to