tracing a program using __import__('__main__')?

Marcus Alanen maalanen at tuxedo.abo.fi
Fri Dec 20 07:53:51 EST 2002


Hi, our program has a set of unittests (everything written in Python).
I'd like to get a view of how good the unittests cover the actual 
program code. This would naturally only be a static view of the code,
not the dynamic execution paths. But at least I could see that some 
tests execute the actual code.

For this, I'm using Python's sys.settrace() to trace the unittest 
program one single code line at a time. Finally I collect all traces 
of all unittests and produce a set of HTML files that show the 
coverage, color-coded. Additionally, the program produces a list of 
functions that have _not_ been used by any test.

Anyway. The unittest programs are executed with execfile().
The problem is that some of the unittests use the "unittest" 
module, which at some point does "__import__('__main__')".
This does not work as inteded. I would've thought it'd give the 
unittest program's scope. Instead it gives the tracing program's 
scope, which I admit is the real __main__. But this means that the 
unittest module doesn't find the actual unittests. :(

(Oh, execfile("myprog.py", { "__name__": "__main__" }) is used
to fake the "if __name__ == '__main__' test in several of the unittest 
scripts. But that's not enough to solve the problem.)

It seems weird that an execfile:d program can break out of the 
namespace "jail" to which it has been constrained.

I haven't tried overloading the __import__ builtin function, basically 
because I don't know what scope I should give back --- there doesn't 
seem to be a way to acquire the scope of the execfile:d program?

I'd rather not change the unittests, even though the change is quite 
small. Others have had the same problem,
http://wingide.com/pipermail/wingide-users/2001-September/000839.html
but no "clean" solution was given.

For those who want to test, the following two programs show the 
problem:


t1.py:
class Foo:
    pass
l = { "__name__": "__main__" }

execfile("t2.py", l, l)


t2.py:
class Bar:
    pass

print __name__

m = __import__("__main__")

print m.__dict__.has_key("Foo")
print m.__dict__.has_key("Bar")


Running "python t1.py" and "python t2.py" produces different results.

Is there any way to fix this, preferably without changing the 
execfile:d program?

Regards,
Marcus

-- 
Marcus Alanen                       * Software Construction Laboratory *
marcus.alanen at abo.fi   * http://www.tucs.fi/Research/labs/softcons.php *




More information about the Python-list mailing list