views:

182

answers:

2

I'm not sure if something like this is even possible in Python, but if it is it'd be really useful (at least to me in this instance).

I have a test framework in which I want to keep the test configuration separate from the test commands. This is useful because it allows you to mix and match configurations/tests without actually having to modify any code. I essentially just a have a short runner script that takes the names of a config module and a test module, then loads and runs both, like so:

config = __import__(configmod)
test = __import__(commandsmod)

config.run(test.commands)

The only problem with this is I'd actually like the test script to have some limited awareness of the configuration parameters. Ideally I'd like to be able to do something like the following in the test/commands module:

command1 = MyCommand(arg1, arg2, LazyArg1())
command2 = MyCommand(arg1, arg2, LazyArg2())
commands = [command1, command2]

where LazyArg1 and LazyArg2 are methods that are defined in the config module (or the runner module that imports both config/commands). Is there any way to delay evaluation of these functions until they are actually defined?

I'd also be open to other ways of achieving the same end. The only other idea I had was to have the config module write a dictionary to file and then have the commands module import that (assuming you just write out repr(mydict)). This isn't very appealing .. though it would work.

A: 

I hate to answer my own question, but after some more thought, I came up with a potential solution (though I'd love to hear other ideas).

Suppose we have a module mod1:

def myfunc(z):
    return z

and a module mod2:

x = lambda mod: mod.myfunc

You can now do the following in a third module:

import mod1
from mod2 import *

x(mod1)(5)

and you end up calling mod1's myfunc. If the double function call is confusing looking, you can assign x(mod1) to another variable name.

Paul D.
A: 

Python is dynamically typed, so this is nothing fancy:

configMod.py:

##### this is configMod.py #####
modTestArg1 = "Brian"

def runTest(testMod, *args, **kwargs):
    testMod.doTest(*args, **kwargs)

testMod.py:

##### this is testMod.py #####
def doTest(name, address, city="San Francisco"):
    print "doTest called with name: %s, address: %s, city: %s" % \
        (name, address, city)

controlMod.py

##### this is controlMod.py #####
import configMod
import testMod

configMod.runTest(testMod, configMod.modTestArg1, "123 Fake Street")

Run it:

python controlMod.py
doTest called with name: Brian, address: 123 Fake Street, city: San Francisco
Peter Lyons