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