tags:

views:

70

answers:

3

I have a wrapper function that returns a function. Is there a way to programmatically set the docstring of the returned function? If I could write to __doc__ I'd do the following:

def wrapper(a):
    def add_something(b):
       return a + b
    add_something.__doc__ = 'Adds ' + str(a) + ' to `b`'
    return add_something

Then I could do

>>> add_three = wrapper(3)
>>> add_three.__doc__
'Adds 3 to `b`

However, since __doc__ is read-only, I can't do that. What's the correct way?


Edit: Ok, I wanted to keep this simple, but of course this is not what I'm actually trying to do. Even though in general __doc__ is writeable in my case it isn't.

I am trying to create testcases for unittest automatically. I have a wrapper function that creates a class object that is a subclass of unittest.TestCase:

import unittest
def makeTestCase(filename, my_func):
    class ATest(unittest.TestCase):
        def testSomething(self):
            # Running test in here with data in filename and function my_func
            data  = loadmat(filename)
            result = my_func(data)
            self.assertTrue(result > 0)

    return ATest

If I create this class and try to set the docstring of testSomething I get an error:

>>> def my_func(): pass
>>> MyTest = makeTestCase('some_filename', my_func)
>>> MyTest.testSomething.__doc__ = 'This should be my docstring'
AttributeError: attribute '__doc__' of 'instancemethod' objects is not writable
+3  A: 

__doc__ isn't read-only.

>>> def foo():
...   return 42
... 
>>> foo.__doc__ = 'bar'
>>> help(foo)
Ignacio Vazquez-Abrams
+3  A: 

__doc__ is not writable only when your object is of type 'type'.

In your case, add_three is a function and you can just set __doc__ to any string.

Satoru.Logic
+2  A: 

I would pass the docstring into the factory function and use type to manually construct the class.

def make_testcase(filename, myfunc, docstring):
    def test_something(self):
        data = loadmat(filename)
        result = myfunc(data)
        self.assertTrue(result > 0)

    clsdict = {'test_something': test_something,
               '__doc__': docstring}
    return type('ATest', (unittest.TestCase,), clsdict)

MyTest = makeTestCase('some_filename', my_func, 'This is a docstring')
aaronasterling