summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coverage/cmdline.py14
-rw-r--r--coverage/execfile.py178
-rw-r--r--tests/modules/pkg1/__main__.py2
-rw-r--r--tests/modules/pkg1/runmod2.py2
-rw-r--r--tests/modules/pkg1/sub/__main__.py2
-rw-r--r--tests/modules/pkg1/sub/runmod3.py2
-rw-r--r--tests/modules/runmod1.py2
-rw-r--r--tests/test_cmdline.py87
-rw-r--r--tests/test_execfile.py44
-rw-r--r--tests/test_process.py18
10 files changed, 214 insertions, 137 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index be258b5e..67efa8db 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -19,7 +19,7 @@ from coverage import env
from coverage.collector import CTracer
from coverage.data import line_counts
from coverage.debug import info_formatter, info_header
-from coverage.execfile import run_python_file, run_python_module
+from coverage.execfile import PyRunner
from coverage.misc import BaseCoverageException, ExceptionDuringRun, NoSource
from coverage.results import should_fail_under
@@ -504,6 +504,10 @@ class CoverageScript(object):
include=include,
)
+ # We need to be able to import from the current directory, because
+ # plugins may try to, for example, to read Django settings.
+ sys.path.insert(0, '')
+
self.coverage.load()
total = None
@@ -633,6 +637,9 @@ class CoverageScript(object):
)
return ERR
+ runner = PyRunner(args, as_module=bool(options.module))
+ runner.prepare()
+
if options.append:
self.coverage.load()
@@ -640,10 +647,7 @@ class CoverageScript(object):
self.coverage.start()
code_ran = True
try:
- if options.module:
- run_python_module(args[0], args)
- else:
- run_python_file(args[0], args)
+ runner.run()
except NoSource:
code_ran = False
raise
diff --git a/coverage/execfile.py b/coverage/execfile.py
index b2b78444..4fc6a85f 100644
--- a/coverage/execfile.py
+++ b/coverage/execfile.py
@@ -3,6 +3,7 @@
"""Execute files of Python code."""
+import inspect
import marshal
import os
import struct
@@ -100,93 +101,99 @@ else:
return pathname, packagename
-def run_python_module(modulename, args):
- """Run a Python module, as though with ``python -m name args...``.
+class PyRunner(object):
+ """Multi-stage execution of Python code.
- `modulename` is the name of the module, possibly a dot-separated name.
- `args` is the argument array to present as sys.argv, including the first
- element naming the module being executed.
+ This is meant to emulate real Python execution as closely as possible.
"""
- pathname, packagename = find_module(modulename)
-
- pathname = os.path.abspath(pathname)
- args[0] = pathname
- # Python 3.7.0b3 changed the behavior of the sys.path[0] entry for -m. It
- # used to be an empty string (meaning the current directory). It changed
- # to be the actual path to the current directory, so that os.chdir wouldn't
- # affect the outcome.
- if env.PYVERSION >= (3, 7, 0, 'beta', 3):
- path0 = os.getcwd()
- else:
- path0 = ""
- run_python_file(pathname, args, package=packagename, modulename=modulename, path0=path0)
-
-
-def run_python_file(filename, args, package=None, modulename=None, path0=None):
- """Run a Python file as if it were the main program on the command line.
+ def __init__(self, args, as_module=False):
+ self.args = args
+ self.as_module = as_module
- `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 naming the file being executed. `package` is the name of the
- enclosing package, if any.
+ self.arg0 = args[0]
+ self.package = self.modulename = self.pathname = None
- `modulename` is the name of the module the file was run as.
+ def prepare(self):
+ """Do initial preparation to run Python code.
- `path0` is the value to put into sys.path[0]. If it's None, then this
- function will decide on a value.
+ Includes finding the module to run, adjusting sys.argv[0], and changing
+ sys.path to match what Python does.
- """
- if modulename is None and env.PYVERSION >= (3, 3):
- modulename = '__main__'
-
- # Create a module to serve as __main__
- old_main_mod = sys.modules['__main__']
- main_mod = types.ModuleType('__main__')
- sys.modules['__main__'] = main_mod
- main_mod.__file__ = filename
- if package:
- main_mod.__package__ = package
- if modulename:
- main_mod.__loader__ = DummyLoader(modulename)
-
- main_mod.__builtins__ = BUILTINS
-
- # Set sys.argv properly.
- old_argv = sys.argv
- sys.argv = args
-
- if os.path.isdir(filename):
- # Running a directory means running the __main__.py file in that
- # directory.
- my_path0 = filename
-
- for ext in [".py", ".pyc", ".pyo"]:
- try_filename = os.path.join(filename, "__main__" + ext)
- if os.path.exists(try_filename):
- filename = try_filename
- break
+ """
+ should_update_sys_path = True
+
+ if self.as_module:
+ # Python 3.7.0b3 changed the behavior of the sys.path[0] entry for -m. It
+ # used to be an empty string (meaning the current directory). It changed
+ # to be the actual path to the current directory, so that os.chdir wouldn't
+ # affect the outcome.
+ if env.PYVERSION >= (3, 7, 0, 'beta', 3):
+ path0 = os.getcwd()
+ else:
+ path0 = ""
+ sys.path[0] = path0
+ should_update_sys_path = False
+ self.modulename = self.arg0
+ pathname, self.package = find_module(self.modulename)
+ self.pathname = os.path.abspath(pathname)
+ self.args[0] = self.arg0 = self.pathname
+ elif os.path.isdir(self.arg0):
+ # Running a directory means running the __main__.py file in that
+ # directory.
+ path0 = self.arg0
+ for ext in [".py", ".pyc", ".pyo"]:
+ try_filename = os.path.join(self.arg0, "__main__" + ext)
+ if os.path.exists(try_filename):
+ self.arg0 = try_filename
+ break
+ else:
+ raise NoSource("Can't find '__main__' module in '%s'" % self.arg0)
else:
- raise NoSource("Can't find '__main__' module in '%s'" % filename)
- else:
- my_path0 = os.path.abspath(os.path.dirname(filename))
-
- # Set sys.path correctly.
- old_path0 = sys.path[0]
- sys.path[0] = path0 if path0 is not None else my_path0
+ path0 = os.path.abspath(os.path.dirname(self.arg0))
+
+ if self.modulename is None and env.PYVERSION >= (3, 3):
+ self.modulename = '__main__'
+
+ if should_update_sys_path:
+ # sys.path fakery. If we are being run as a command, then sys.path[0]
+ # is the directory of the "coverage" script. If this is so, replace
+ # sys.path[0] with the directory of the file we're running, or the
+ # current directory when running modules. If it isn't so, then we
+ # don't know what's going on, and just leave it alone.
+ top_file = inspect.stack()[-1][0].f_code.co_filename
+ if os.path.abspath(sys.path[0]) == os.path.abspath(os.path.dirname(top_file)):
+ # Set sys.path correctly.
+ sys.path[0] = path0
+
+ def run(self):
+ """Run the Python code!"""
+
+ # Create a module to serve as __main__
+ main_mod = types.ModuleType('__main__')
+ sys.modules['__main__'] = main_mod
+ main_mod.__file__ = self.arg0
+ if self.package:
+ main_mod.__package__ = self.package
+ if self.modulename:
+ main_mod.__loader__ = DummyLoader(self.modulename)
+
+ main_mod.__builtins__ = BUILTINS
+
+ # Set sys.argv properly.
+ sys.argv = self.args
- try:
try:
# Make a code object somehow.
- if filename.endswith((".pyc", ".pyo")):
- code = make_code_from_pyc(filename)
+ if self.arg0.endswith((".pyc", ".pyo")):
+ code = make_code_from_pyc(self.arg0)
else:
- code = make_code_from_py(filename)
+ code = make_code_from_py(self.arg0)
except CoverageException:
raise
except Exception as exc:
msg = "Couldn't run {filename!r} as Python code: {exc.__class__.__name__}: {exc}"
- raise CoverageException(msg.format(filename=filename, exc=exc))
+ raise CoverageException(msg.format(filename=self.arg0, exc=exc))
# Execute the code object.
try:
@@ -230,11 +237,30 @@ def run_python_file(filename, args, package=None, modulename=None, path0=None):
else:
sys.exit(1)
- finally:
- # Restore the old __main__, argv, and path.
- sys.modules['__main__'] = old_main_mod
- sys.argv = old_argv
- sys.path[0] = old_path0
+
+def run_python_module(args):
+ """Run a Python module, as though with ``python -m name args...``.
+
+ `args` is the argument array to present as sys.argv, including the first
+ element naming the module being executed.
+
+ """
+ runner = PyRunner(args, as_module=True)
+ runner.prepare()
+ runner.run()
+
+
+def run_python_file(args):
+ """Run a Python file as if it were the main program on the command line.
+
+ `args` is the argument array to present as sys.argv, including the first
+ element naming the file being executed. `package` is the name of the
+ enclosing package, if any.
+
+ """
+ runner = PyRunner(args, as_module=False)
+ runner.prepare()
+ runner.run()
def make_code_from_py(filename):
diff --git a/tests/modules/pkg1/__main__.py b/tests/modules/pkg1/__main__.py
index 66ce5956..0d38e33e 100644
--- a/tests/modules/pkg1/__main__.py
+++ b/tests/modules/pkg1/__main__.py
@@ -1,3 +1,3 @@
-# Used in the tests for run_python_module
+# Used in the tests for PyRunner
import sys
print("pkg1.__main__: passed %s" % sys.argv[1])
diff --git a/tests/modules/pkg1/runmod2.py b/tests/modules/pkg1/runmod2.py
index b0f43c2e..e2778669 100644
--- a/tests/modules/pkg1/runmod2.py
+++ b/tests/modules/pkg1/runmod2.py
@@ -1,6 +1,6 @@
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
-# Used in the tests for run_python_module
+# Used in the tests for PyRunner
import sys
print("runmod2: passed %s" % sys.argv[1])
diff --git a/tests/modules/pkg1/sub/__main__.py b/tests/modules/pkg1/sub/__main__.py
index b5be9f1c..1af82c43 100644
--- a/tests/modules/pkg1/sub/__main__.py
+++ b/tests/modules/pkg1/sub/__main__.py
@@ -1,3 +1,3 @@
-# Used in the tests for run_python_module
+# Used in the tests for PyRunner
import sys
print("pkg1.sub.__main__: passed %s" % sys.argv[1])
diff --git a/tests/modules/pkg1/sub/runmod3.py b/tests/modules/pkg1/sub/runmod3.py
index b3b40327..d2be9e5c 100644
--- a/tests/modules/pkg1/sub/runmod3.py
+++ b/tests/modules/pkg1/sub/runmod3.py
@@ -1,6 +1,6 @@
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
-# Used in the tests for run_python_module
+# Used in the tests for PyRunner
import sys
print("runmod3: passed %s" % sys.argv[1])
diff --git a/tests/modules/runmod1.py b/tests/modules/runmod1.py
index cb1f7e99..f79fae83 100644
--- a/tests/modules/runmod1.py
+++ b/tests/modules/runmod1.py
@@ -1,6 +1,6 @@
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
-# Used in the tests for run_python_module
+# Used in the tests for PyRunner
import sys
print("runmod1: passed %s" % sys.argv[1])
diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py
index 18702c96..fd2821b0 100644
--- a/tests/test_cmdline.py
+++ b/tests/test_cmdline.py
@@ -71,7 +71,7 @@ class BaseCmdLineTest(CoverageTest):
return mk
# Global names in cmdline.py that will be mocked during the tests.
- MOCK_GLOBALS = ['Coverage', 'run_python_file', 'run_python_module']
+ MOCK_GLOBALS = ['Coverage', 'PyRunner']
def mock_command_line(self, args, options=None):
"""Run `args` through the command line, with a Mock.
@@ -371,98 +371,113 @@ class CmdLineTest(BaseCmdLineTest):
# run calls coverage.erase first.
self.cmd_executes("run foo.py", """\
cov = Coverage()
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
# run -a combines with an existing data file before saving.
self.cmd_executes("run -a foo.py", """\
cov = Coverage()
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.load()
cov.start()
- run_python_file('foo.py', ['foo.py'])
- cov.stop()
- cov.save()
- """)
- # run -a doesn't combine anything if the data file doesn't exist.
- self.cmd_executes("run -a foo.py", """\
- cov = Coverage()
- cov.load()
- cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
# --timid sets a flag, and program arguments get passed through.
self.cmd_executes("run --timid foo.py abc 123", """\
cov = Coverage(timid=True)
+ runner = PyRunner(['foo.py', 'abc', '123'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py', 'abc', '123'])
+ runner.run()
cov.stop()
cov.save()
""")
# -L sets a flag, and flags for the program don't confuse us.
self.cmd_executes("run -p -L foo.py -a -b", """\
cov = Coverage(cover_pylib=True, data_suffix=True)
+ runner = PyRunner(['foo.py', '-a', '-b'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py', '-a', '-b'])
+ runner.run()
cov.stop()
cov.save()
""")
self.cmd_executes("run --branch foo.py", """\
cov = Coverage(branch=True)
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
self.cmd_executes("run --rcfile=myrc.rc foo.py", """\
cov = Coverage(config_file="myrc.rc")
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
self.cmd_executes("run --include=pre1,pre2 foo.py", """\
cov = Coverage(include=["pre1", "pre2"])
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
self.cmd_executes("run --omit=opre1,opre2 foo.py", """\
cov = Coverage(omit=["opre1", "opre2"])
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
self.cmd_executes("run --include=pre1,pre2 --omit=opre1,opre2 foo.py", """\
cov = Coverage(include=["pre1", "pre2"], omit=["opre1", "opre2"])
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
self.cmd_executes("run --source=quux,hi.there,/home/bar foo.py", """\
cov = Coverage(source=["quux", "hi.there", "/home/bar"])
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
self.cmd_executes("run --concurrency=gevent foo.py", """\
cov = Coverage(concurrency='gevent')
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
self.cmd_executes("run --concurrency=multiprocessing foo.py", """\
cov = Coverage(concurrency='multiprocessing')
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
@@ -497,15 +512,19 @@ class CmdLineTest(BaseCmdLineTest):
def test_run_debug(self):
self.cmd_executes("run --debug=opt1 foo.py", """\
cov = Coverage(debug=["opt1"])
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
self.cmd_executes("run --debug=opt1,opt2 foo.py", """\
cov = Coverage(debug=["opt1","opt2"])
+ runner = PyRunner(['foo.py'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('foo.py', ['foo.py'])
+ runner.run()
cov.stop()
cov.save()
""")
@@ -513,22 +532,28 @@ class CmdLineTest(BaseCmdLineTest):
def test_run_module(self):
self.cmd_executes("run -m mymodule", """\
cov = Coverage()
+ runner = PyRunner(['mymodule'], as_module=True)
+ runner.prepare()
cov.start()
- run_python_module('mymodule', ['mymodule'])
+ runner.run()
cov.stop()
cov.save()
""")
self.cmd_executes("run -m mymodule -qq arg1 arg2", """\
cov = Coverage()
+ runner = PyRunner(['mymodule', '-qq', 'arg1', 'arg2'], as_module=True)
+ runner.prepare()
cov.start()
- run_python_module('mymodule', ['mymodule', '-qq', 'arg1', 'arg2'])
+ runner.run()
cov.stop()
cov.save()
""")
self.cmd_executes("run --branch -m mymodule", """\
cov = Coverage(branch=True)
+ runner = PyRunner(['mymodule'], as_module=True)
+ runner.prepare()
cov.start()
- run_python_module('mymodule', ['mymodule'])
+ runner.run()
cov.stop()
cov.save()
""")
@@ -542,8 +567,10 @@ class CmdLineTest(BaseCmdLineTest):
options = {"run:command_line": "myprog.py a 123 'a quoted thing' xyz"}
self.cmd_executes("run", """\
cov = Coverage()
+ runner = PyRunner(['myprog.py', 'a', '123', 'a quoted thing', 'xyz'], as_module=False)
+ runner.prepare()
cov.start()
- run_python_file('myprog.py', ['myprog.py', 'a', '123', 'a quoted thing', 'xyz'])
+ runner.run()
cov.stop()
cov.save()
""",
@@ -553,8 +580,10 @@ class CmdLineTest(BaseCmdLineTest):
def test_run_module_from_config(self):
self.cmd_executes("run", """\
cov = Coverage()
+ runner = PyRunner(['mymodule', 'thing1', 'thing2'], as_module=True)
+ runner.prepare()
cov.start()
- run_python_module('mymodule', ['mymodule', 'thing1', 'thing2'])
+ runner.run()
cov.stop()
cov.save()
""",
diff --git a/tests/test_execfile.py b/tests/test_execfile.py
index cb835c2a..ced4c28f 100644
--- a/tests/test_execfile.py
+++ b/tests/test_execfile.py
@@ -23,7 +23,7 @@ class RunFileTest(CoverageTest):
"""Test cases for `run_python_file`."""
def test_run_python_file(self):
- run_python_file(TRY_EXECFILE, [TRY_EXECFILE, "arg1", "arg2"])
+ run_python_file([TRY_EXECFILE, "arg1", "arg2"])
mod_globs = json.loads(self.stdout())
# The file should think it is __main__
@@ -56,7 +56,7 @@ class RunFileTest(CoverageTest):
""")
self.assertEqual(os.listdir("."), ["xxx"])
- run_python_file("xxx", ["xxx"])
+ run_python_file(["xxx"])
self.assertEqual(os.listdir("."), ["xxx"])
def test_universal_newlines(self):
@@ -65,7 +65,7 @@ class RunFileTest(CoverageTest):
for nl in ('\n', '\r\n', '\r'):
with open('nl.py', 'wb') as fpy:
fpy.write(nl.join(pylines).encode('utf-8'))
- run_python_file('nl.py', ['nl.py'])
+ run_python_file(['nl.py'])
self.assertEqual(self.stdout(), "Hello, world!\n"*3)
def test_missing_final_newline(self):
@@ -78,24 +78,24 @@ class RunFileTest(CoverageTest):
with open("abrupt.py") as f:
abrupt = f.read()
self.assertEqual(abrupt[-1], '#')
- run_python_file("abrupt.py", ["abrupt.py"])
+ run_python_file(["abrupt.py"])
self.assertEqual(self.stdout(), "a is 1\n")
def test_no_such_file(self):
with self.assertRaises(NoSource):
- run_python_file("xyzzy.py", [])
+ run_python_file(["xyzzy.py"])
def test_directory_with_main(self):
self.make_file("with_main/__main__.py", """\
print("I am __main__")
""")
- run_python_file("with_main", ["with_main"])
+ run_python_file(["with_main"])
self.assertEqual(self.stdout(), "I am __main__\n")
def test_directory_without_main(self):
self.make_file("without_main/__init__.py", "")
with self.assertRaisesRegex(NoSource, "Can't find '__main__' module in 'without_main'"):
- run_python_file("without_main", ["without_main"])
+ run_python_file(["without_main"])
class RunPycFileTest(CoverageTest):
@@ -123,7 +123,7 @@ class RunPycFileTest(CoverageTest):
def test_running_pyc(self):
pycfile = self.make_pyc()
- run_python_file(pycfile, [pycfile])
+ run_python_file([pycfile])
self.assertEqual(self.stdout(), "I am here!\n")
def test_running_pyo(self):
@@ -131,7 +131,7 @@ class RunPycFileTest(CoverageTest):
pyofile = re.sub(r"[.]pyc$", ".pyo", pycfile)
self.assertNotEqual(pycfile, pyofile)
os.rename(pycfile, pyofile)
- run_python_file(pyofile, [pyofile])
+ run_python_file([pyofile])
self.assertEqual(self.stdout(), "I am here!\n")
def test_running_pyc_from_wrong_python(self):
@@ -143,11 +143,11 @@ class RunPycFileTest(CoverageTest):
fpyc.write(binary_bytes([0x2a, 0xeb, 0x0d, 0x0a]))
with self.assertRaisesRegex(NoCode, "Bad magic number in .pyc file"):
- run_python_file(pycfile, [pycfile])
+ run_python_file([pycfile])
def test_no_such_pyc_file(self):
with self.assertRaisesRegex(NoCode, "No file to run: 'xyzzy.pyc'"):
- run_python_file("xyzzy.pyc", [])
+ run_python_file(["xyzzy.pyc"])
def test_running_py_from_binary(self):
# Use make_file to get the bookkeeping. Ideally, it would
@@ -166,7 +166,7 @@ class RunPycFileTest(CoverageTest):
r")"
)
with self.assertRaisesRegex(Exception, msg):
- run_python_file(bf, [bf])
+ run_python_file([bf])
class RunModuleTest(UsingModulesMixin, CoverageTest):
@@ -175,43 +175,43 @@ class RunModuleTest(UsingModulesMixin, CoverageTest):
run_in_temp_dir = False
def test_runmod1(self):
- run_python_module("runmod1", ["runmod1", "hello"])
+ run_python_module(["runmod1", "hello"])
self.assertEqual(self.stderr(), "")
self.assertEqual(self.stdout(), "runmod1: passed hello\n")
def test_runmod2(self):
- run_python_module("pkg1.runmod2", ["runmod2", "hello"])
+ run_python_module(["pkg1.runmod2", "hello"])
self.assertEqual(self.stderr(), "")
self.assertEqual(self.stdout(), "pkg1.__init__: pkg1\nrunmod2: passed hello\n")
def test_runmod3(self):
- run_python_module("pkg1.sub.runmod3", ["runmod3", "hello"])
+ run_python_module(["pkg1.sub.runmod3", "hello"])
self.assertEqual(self.stderr(), "")
self.assertEqual(self.stdout(), "pkg1.__init__: pkg1\nrunmod3: passed hello\n")
def test_pkg1_main(self):
- run_python_module("pkg1", ["pkg1", "hello"])
+ run_python_module(["pkg1", "hello"])
self.assertEqual(self.stderr(), "")
self.assertEqual(self.stdout(), "pkg1.__init__: pkg1\npkg1.__main__: passed hello\n")
def test_pkg1_sub_main(self):
- run_python_module("pkg1.sub", ["pkg1.sub", "hello"])
+ run_python_module(["pkg1.sub", "hello"])
self.assertEqual(self.stderr(), "")
self.assertEqual(self.stdout(), "pkg1.__init__: pkg1\npkg1.sub.__main__: passed hello\n")
def test_pkg1_init(self):
- run_python_module("pkg1.__init__", ["pkg1.__init__", "wut?"])
+ run_python_module(["pkg1.__init__", "wut?"])
self.assertEqual(self.stderr(), "")
self.assertEqual(self.stdout(), "pkg1.__init__: pkg1\npkg1.__init__: __main__\n")
def test_no_such_module(self):
with self.assertRaises(NoSource):
- run_python_module("i_dont_exist", [])
+ run_python_module(["i_dont_exist"])
with self.assertRaises(NoSource):
- run_python_module("i.dont_exist", [])
+ run_python_module(["i.dont_exist"])
with self.assertRaises(NoSource):
- run_python_module("i.dont.exist", [])
+ run_python_module(["i.dont.exist"])
def test_no_main(self):
with self.assertRaises(NoSource):
- run_python_module("pkg2", ["pkg2", "hi"])
+ run_python_module(["pkg2", "hi"])
diff --git a/tests/test_process.py b/tests/test_process.py
index 9f7a16f5..bba58c54 100644
--- a/tests/test_process.py
+++ b/tests/test_process.py
@@ -861,6 +861,13 @@ class EnvironmentTest(CoverageTest):
actual = self.run_command("coverage run run_me.py")
self.assert_tryexecfile_output(expected, actual)
+ def test_coverage_run_far_away_is_like_python(self):
+ with open(TRY_EXECFILE) as f:
+ self.make_file("sub/overthere/prog.py", f.read())
+ expected = self.run_command("python sub/overthere/prog.py")
+ actual = self.run_command("coverage run sub/overthere/prog.py")
+ self.assert_tryexecfile_output(expected, actual)
+
def test_coverage_run_dashm_is_like_python_dashm(self):
# These -m commands assume the coverage tree is on the path.
expected = self.run_command("python -m process_test.try_execfile")
@@ -904,6 +911,17 @@ class EnvironmentTest(CoverageTest):
def test_coverage_run_dashm_superset_of_doubledashsource(self):
"""Edge case: --source foo -m foo.bar"""
+ # Ugh: without this config file, we'll get a warning about
+ # Coverage.py warning: Module process_test was previously imported,
+ # but not measured (module-not-measured)
+ #
+ # This is because process_test/__init__.py is imported while looking
+ # for process_test.try_execfile. That import happens while setting
+ # sys.path before start() is called.
+ self.make_file(".coveragerc", """\
+ [run]
+ disable_warnings = module-not-measured
+ """)
# These -m commands assume the coverage tree is on the path.
expected = self.run_command("python -m process_test.try_execfile")
actual = self.run_command(