Doctest and Decorators in Python
Question: I was trying to use Python decorator to catch exceptions and log the
exceptions.

    
    
    import os.path
    import shutil
    
    class log(object):
        def __init__(self, f):
            print "Inside __init__()"
            self.f = f
    
        def __call__(self, *args):
            print "Inside __call__()"
            try:
                self.f(*args)
            except Exception:
                print "Sorry"
    
    @log
    def testit(a, b, c):
        print a,b,c
        raise RuntimeError()
    
    if __name__ == "__main__":
        testit(1,2,3)
    

It works fine

    
    
    Desktop> python deco.py 
    Inside __init__()
    Inside __call__()
    1 2 3
    Sorry
    

The issue is that when I tried to use for testing with doctest

    
    
    @log
    def testit(a, b, c):
        """
        >>> testit(1,2,3)
        """
        print a,b,c
        raise RuntimeError()
    
    if __name__ == "__main__":
        import doctest
        doctest.testmod()
    

nothing seems to be happening.

    
    
    Desktop> python deco2.py 
    Inside __init__()
    

What's wrong with this?


Answer: The decorated function (which is actually a class instance) doesn't get the
`__doc__` attribute of the original function (which is what `doctest` parses).
You _could_ just copy `__doc__` over to the class instance, but ... Honestly,
I don't really see the need for a class at all here -- you'd probably be
better just using `functools.wraps`

    
    
    import functools
    def log(func):
        @functools.wraps(func)
        def wrapper(*args):
            try:
                return func(*args)
            except Exception:
                print "sorry"
        return wrapper
    

