Python Introspection: Defining dynamic class methods during runtime
Question: I'm trying to create a unit test, that checks that every function in
`mymodule` has its own `TestCase` instance.  
To reduce boiler-plate code and manual effort I wanted to use
introspection/reflection to dynamically add `lambda` functions as class
methods to the initially empty class `Test_TestCases`.  
The following code kind of works - it does indeed add lambdas as class methods
and `unittest.main()` finds and correctly calls them.

    
    
    import unittest
    from unittest import TestCase
    
    import mymodule
    
    class Test_TestCases(TestCase):
    """Class whose test_* methods will be created during runtime."""
        pass
    
    ################################################################################
    
    if __name__ == "__main__":
        for item in dir(mymodule):
            attr = getattr(pws, item)
            if callable(attr):
                testname = "Test_%s" % item
                setattr(Test_TestCases, "test_%s_is_tested" % item,
                        lambda self: self.assertTrue(testname in globals()) and
                        issubclass(getattr(globals(), testname), TestCase))
        unittest.main()
    

The problem is, that all tests succeed even though I do have untested
functions in my unit test module.  
After a little trying around I figured out that the variable `testname` has
the same value every time the `lambda` is called.  
I could minimize the problem to this piece of code for reproducability:

    
    
    lambdas = []
    for i in range(5):
        lambdas.append(lambda: str(i))
    print ", ".join(f() for f in lambdas)
    

I'd expect this output:

    
    
    0, 1, 2, 3, 4
    

but instead I get:

    
    
    4, 4, 4, 4, 4
    

It seems that the lambdas are initialized lazily.  
Could anyone please explain this behaviour or give me a hint on how I would
accomplish my goal properly?

Thanks in advance


Answer: Shadow `testname` with another wrapper function:

    
    
    def assertion(testname=testname):
        def function(self):
            return self.assertTrue(testname in globals()) and issubclass(getattr(globals(), testname), TestCase))
    
        return function
    
    setattr(Test_TestCases, "test_%s_is_tested" % item, assertion())
    

