summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.pylintrc3
-rw-r--r--coverage/execfile.py38
-rw-r--r--test/test_execfile.py26
3 files changed, 36 insertions, 31 deletions
diff --git a/.pylintrc b/.pylintrc
index ba962001..5d343282 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -55,6 +55,7 @@ load-plugins=
# Disable the message(s) with the given id(s).
# Messages that are just silly:
# I0011:106: Locally disabling E1101
+# W0122: 30:run_python_file: Use of the exec statement
# W0142: 31:call_singleton_method: Used * or ** magic
# W0232: 6:AnyOldObject: Class has no __init__ method
# C0323:311:coverage.report: Operator not followed by a space
@@ -67,7 +68,7 @@ load-plugins=
# Messages that are noisy for now, eventually maybe we'll turn them on:
# C0111:169:coverage.analyze_morf: Missing docstring
# C0103:256:coverage.morf_filename: Invalid name "f" (should match [a-z_][a-z0-9_]{2,30}$)
-disable-msg=I0011,W0142,W0232,C0323,C0324,W0603, R0201,W0403,E1103, C0111,C0103
+disable-msg=I0011,W0122,W0142,W0232,C0323,C0324,W0603, R0201,W0403,E1103, C0111,C0103
[REPORTS]
diff --git a/coverage/execfile.py b/coverage/execfile.py
index c957949e..e066e205 100644
--- a/coverage/execfile.py
+++ b/coverage/execfile.py
@@ -3,25 +3,35 @@
import imp, os, sys
def run_python_file(filename, args):
- """Run a python source file as if it were the main program on the python
- command line.
+ """Run a python file as if it were the main program on the command line.
- `filename` is the path to the file to execute, must be a .py file.
- `args` is the argument array to present as sys.argv.
+ `filename` is the path to the file to execute, it need not be a .py file.
+ `args` is the argument array to present as sys.argv, including the first
+ element representing the file being executed.
"""
- # Most code that does this does it in a way that leaves __main__ or
- # __file__ with the wrong values. Importing the code as __main__ gets all
- # of this right automatically.
- #
- # One difference from python.exe: if I run foo.py from the command line, it
- # always uses foo.py. With this code, it might find foo.pyc instead.
-
+ # Create a module to serve as __main__
+ old_main_mod = sys.modules['__main__']
+ main_mod = imp.new_module("__main__")
+ sys.modules['__main__'] = main_mod
+ main_mod.__dict__.update({
+ '__name__': '__main__',
+ '__file__': filename,
+ })
+
+ # Set sys.argv and the first path element properly.
+ old_argv = sys.argv
+ old_path0 = sys.path[0]
sys.argv = args
sys.path[0] = os.path.dirname(filename)
- src = open(filename)
try:
- imp.load_module('__main__', src, filename, (".py", "r", imp.PY_SOURCE))
+ source = open(filename).read()
+ exec compile(source, filename, "exec") in main_mod.__dict__
finally:
- src.close()
+ # Restore the old __main__
+ sys.modules['__main__'] = old_main_mod
+
+ # Restore the old argv and path
+ sys.argv = old_argv
+ sys.path[0] = old_path0
diff --git a/test/test_execfile.py b/test/test_execfile.py
index 60ef1952..fc5b52a4 100644
--- a/test/test_execfile.py
+++ b/test/test_execfile.py
@@ -17,11 +17,9 @@ class RunTest(CoverageTest):
# The file should think it is __main__
self.assertEqual(mod_globs['__name__'], "__main__")
- # It should seem to come from a file named try_execfile
- dunder_file = os.path.splitext(
- os.path.basename(mod_globs['__file__'])
- )[0]
- self.assertEqual(dunder_file, "try_execfile")
+ # It should seem to come from a file named try_execfile.py
+ dunder_file = os.path.basename(mod_globs['__file__'])
+ self.assertEqual(dunder_file, "try_execfile.py")
# It should have its correct module data.
self.assertEqual(mod_globs['__doc__'],
@@ -35,16 +33,12 @@ class RunTest(CoverageTest):
# Argv should have the proper values.
self.assertEqual(mod_globs['argv'], [tryfile, "arg1", "arg2"])
- def test_no_c_file(self):
- self.makeFile("mycode.py", """\
- a = 1
- b = 2
- if b == 3:
- c = 4
- d = 5
+ def test_no_extra_file(self):
+ # Make sure that running a file doesn't create an extra compiled file.
+ self.makeFile("xxx", """\
+ print "a non-.py file!"
""")
- self.assert_(not os.path.exists(".coverage"))
- self.run_command("coverage -x mycode.py")
- self.assert_(os.path.exists(".coverage"))
- \ No newline at end of file
+ self.assertEqual(os.listdir("."), ["xxx"])
+ run_python_file("xxx", ["xxx"])
+ self.assertEqual(os.listdir("."), ["xxx"])