summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2013-04-20 19:10:51 -0400
committerNed Batchelder <ned@nedbatchelder.com>2013-04-20 19:10:51 -0400
commitf5cfe193a73b08990fddd888167b6c6336b6803c (patch)
treea42f9e8a104eca8763ce0ded47b594c4891b1415
parent351264bd7deff3fdf6e393581560b4d994c1dbfa (diff)
downloadpython-coveragepy-git-f5cfe193a73b08990fddd888167b6c6336b6803c.tar.gz
Get sys.path right when running modules with -m, fixes #207 and #242.
-rw-r--r--CHANGES.txt6
-rw-r--r--coverage/cmdline.py13
-rw-r--r--coverage/execfile.py9
-rw-r--r--tests/test_process.py43
4 files changed, 46 insertions, 25 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 82b1b84f..0f497402 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -7,13 +7,17 @@ Change history for Coverage.py
- Improved the branch coverage mechanism, fixing `issue 175`_.
+- Running code with ``coverage run -m`` now behaves more like Python does,
+ setting sys.path properly, which fixes `issue 207`_ and `issue 242`.
+
- When running a threaded program under the Python tracer, coverage would issue
a spurious warning about the trace function changing: "Trace function
changed, measurement is likely wrong: None." This is now fixed.
.. _issue 164: https://bitbucket.org/ned/coveragepy/issue/164/trace-function-changed-warning-when-using
.. _issue 175: https://bitbucket.org/ned/coveragepy/issue/175/branch-coverage-gets-confused-in-certain
-
+.. _issue 207: https://bitbucket.org/ned/coveragepy/issue/207/run-m-cannot-find-module-or-package-in
+.. _issue 242: https://bitbucket.org/ned/coveragepy/issue/242/running-a-two-level-package-doesnt-work
Version 3.6 --- 5 January 2013
------------------------------
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index cb1d7a3e..ac803109 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -1,6 +1,6 @@
"""Command-line support for Coverage."""
-import optparse, sys, traceback
+import optparse, os, sys, traceback
from coverage.backward import sorted # pylint: disable=W0622
from coverage.execfile import run_python_file, run_python_module
@@ -549,15 +549,21 @@ class CoverageScript(object):
def do_execute(self, options, args):
"""Implementation of 'coverage run'."""
+ # Set the first path element properly.
+ old_path0 = sys.path[0]
+
# Run the script.
self.coverage.start()
code_ran = True
try:
try:
if options.module:
+ sys.path[0] = ''
self.run_python_module(args[0], args)
else:
- self.run_python_file(args[0], args)
+ filename = args[0]
+ sys.path[0] = os.path.abspath(os.path.dirname(filename))
+ self.run_python_file(filename, args)
except NoSource:
code_ran = False
raise
@@ -566,6 +572,9 @@ class CoverageScript(object):
if code_ran:
self.coverage.save()
+ # Restore the old path
+ sys.path[0] = old_path0
+
def do_debug(self, args):
"""Implementation of 'coverage debug'."""
diff --git a/coverage/execfile.py b/coverage/execfile.py
index 587c2d3c..fbb49b2a 100644
--- a/coverage/execfile.py
+++ b/coverage/execfile.py
@@ -65,6 +65,7 @@ def run_python_module(modulename, args):
openfile.close()
# Finally, hand the file off to run_python_file for execution.
+ pathname = os.path.abspath(pathname)
args[0] = pathname
run_python_file(pathname, args, package=packagename)
@@ -87,14 +88,9 @@ def run_python_file(filename, args, package=None):
main_mod.__package__ = package
main_mod.__builtins__ = BUILTINS
- # Set sys.argv and the first path element properly.
+ # Set sys.argv properly.
old_argv = sys.argv
- old_path0 = sys.path[0]
sys.argv = args
- if package:
- sys.path[0] = ''
- else:
- sys.path[0] = os.path.abspath(os.path.dirname(filename))
try:
# Open the source file.
@@ -135,4 +131,3 @@ def run_python_file(filename, args, package=None):
# Restore the old argv and path
sys.argv = old_argv
- sys.path[0] = old_path0
diff --git a/tests/test_process.py b/tests/test_process.py
index 8e31bd18..8554eb54 100644
--- a/tests/test_process.py
+++ b/tests/test_process.py
@@ -320,25 +320,38 @@ class ProcessTest(CoverageTest):
def test_coverage_run_is_like_python(self):
tryfile = os.path.join(here, "try_execfile.py")
self.make_file("run_me.py", open(tryfile).read())
- out = self.run_command("coverage run run_me.py")
- out2 = self.run_command("python run_me.py")
- self.assertMultiLineEqual(out, out2)
+ out_cov = self.run_command("coverage run run_me.py")
+ out_py = self.run_command("python run_me.py")
+ self.assertMultiLineEqual(out_cov, out_py)
- if sys.version_info >= (2, 6): # Doesn't work in 2.5, and I don't care!
+ if sys.version_info >= (2, 6):
+ # Doesn't work in 2.5, and I don't care! For some reason, python -m
+ # in 2.5 has __builtins__ as a dictionary instead of a module?
def test_coverage_run_dashm_is_like_python_dashm(self):
# These -m commands assume the coverage tree is on the path.
- out = self.run_command("coverage run -m tests.try_execfile")
- out2 = self.run_command("python -m tests.try_execfile")
- self.assertMultiLineEqual(out, out2)
-
- if 0: # Expected failure
- # For https://bitbucket.org/ned/coveragepy/issue/207
+ out_cov = self.run_command("coverage run -m tests.try_execfile")
+ out_py = self.run_command("python -m tests.try_execfile")
+ self.assertMultiLineEqual(out_cov, out_py)
+
+ def test_coverage_run_dashm_is_like_python_dashm_off_path(self):
+ # https://bitbucket.org/ned/coveragepy/issue/242
+ tryfile = os.path.join(here, "try_execfile.py")
+ self.make_file("sub/__init__.py", "")
+ self.make_file("sub/run_me.py", open(tryfile).read())
+ out_cov = self.run_command("coverage run -m sub.run_me")
+ out_py = self.run_command("python -m sub.run_me")
+ self.assertMultiLineEqual(out_cov, out_py)
+
+ if sys.version_info >= (2, 7):
+ # Coverage isn't bug-for-bug compatible in the behavior of -m for
+ # Pythons < 2.7
def test_coverage_run_dashm_is_like_python_dashm_with__main__207(self):
- self.make_file("package/__init__.py") # empty
- self.make_file("package/__main__.py", "#\n") # empty
- out = self.run_command("coverage run -m package")
- out2 = self.run_command("python -m package")
- self.assertMultiLineEqual(out, out2)
+ # https://bitbucket.org/ned/coveragepy/issue/207
+ self.make_file("package/__init__.py", "print('init')")
+ self.make_file("package/__main__.py", "print('main')")
+ out_cov = self.run_command("coverage run -m package")
+ out_py = self.run_command("python -m package")
+ self.assertMultiLineEqual(out_cov, out_py)
if hasattr(os, 'fork'):
def test_fork(self):