]> granicus.if.org Git - python/commitdiff
bpo-31908: Fix output of cover files for trace module command-line tool. (GH-4205)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 1 May 2018 05:03:29 +0000 (22:03 -0700)
committerGitHub <noreply@github.com>
Tue, 1 May 2018 05:03:29 +0000 (22:03 -0700)
Previously emitted cover files only when --missing option was used.
(cherry picked from commit 47ab15470d72367694d7758004067313ae022f0e)

Co-authored-by: Michael Selik <mike@selik.org>
Lib/test/test_trace.py
Lib/trace.py
Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst [new file with mode: 0644]

index e04ca01c4299891bcae99aa45ad780f34186bc23..55a8bcea3e546ad9657155816b3b59ebc0330363 100644 (file)
@@ -2,6 +2,7 @@ import os
 import sys
 from test.support import TESTFN, rmtree, unlink, captured_stdout
 from test.support.script_helper import assert_python_ok, assert_python_failure
+import textwrap
 import unittest
 
 import trace
@@ -365,6 +366,46 @@ class Test_Ignore(unittest.TestCase):
         # Matched before.
         self.assertTrue(ignore.names(jn('bar', 'baz.py'), 'baz'))
 
+# Created for Issue 31908 -- CLI utility not writing cover files
+class TestCoverageCommandLineOutput(unittest.TestCase):
+
+    codefile = 'tmp.py'
+    coverfile = 'tmp.cover'
+
+    def setUp(self):
+        with open(self.codefile, 'w') as f:
+            f.write(textwrap.dedent('''\
+                x = 42
+                if []:
+                    print('unreachable')
+            '''))
+
+    def tearDown(self):
+        unlink(self.codefile)
+        unlink(self.coverfile)
+
+    def test_cover_files_written_no_highlight(self):
+        argv = '-m trace --count'.split() + [self.codefile]
+        status, stdout, stderr = assert_python_ok(*argv)
+        self.assertTrue(os.path.exists(self.coverfile))
+        with open(self.coverfile) as f:
+            self.assertEqual(f.read(),
+                "    1: x = 42\n"
+                "    1: if []:\n"
+                "           print('unreachable')\n"
+            )
+
+    def test_cover_files_written_with_highlight(self):
+        argv = '-m trace --count --missing'.split() + [self.codefile]
+        status, stdout, stderr = assert_python_ok(*argv)
+        self.assertTrue(os.path.exists(self.coverfile))
+        with open(self.coverfile) as f:
+            self.assertEqual(f.read(), textwrap.dedent('''\
+                    1: x = 42
+                    1: if []:
+                >>>>>>     print('unreachable')
+            '''))
+
 class TestCommandLine(unittest.TestCase):
 
     def test_failures(self):
index 9ba9486bd024752c03c2077eeffde9273a6497e8..d171577e39917c92dc65f30575854bf190549a0f 100755 (executable)
@@ -79,9 +79,6 @@ else:
 
 PRAGMA_NOCOVER = "#pragma NO COVER"
 
-# Simple rx to find lines with no code.
-rx_blank = re.compile(r'^\s*(#.*)?$')
-
 class _Ignore:
     def __init__(self, modules=None, dirs=None):
         self._mods = set() if not modules else set(modules)
@@ -284,16 +281,15 @@ class CoverageResults:
                 lnotab = _find_executable_linenos(filename)
             else:
                 lnotab = {}
-            if lnotab:
-                source = linecache.getlines(filename)
-                coverpath = os.path.join(dir, modulename + ".cover")
-                with open(filename, 'rb') as fp:
-                    encoding, _ = tokenize.detect_encoding(fp.readline)
-                n_hits, n_lines = self.write_results_file(coverpath, source,
-                                                          lnotab, count, encoding)
-                if summary and n_lines:
-                    percent = int(100 * n_hits / n_lines)
-                    sums[modulename] = n_lines, percent, modulename, filename
+            source = linecache.getlines(filename)
+            coverpath = os.path.join(dir, modulename + ".cover")
+            with open(filename, 'rb') as fp:
+                encoding, _ = tokenize.detect_encoding(fp.readline)
+            n_hits, n_lines = self.write_results_file(coverpath, source,
+                                                      lnotab, count, encoding)
+            if summary and n_lines:
+                percent = int(100 * n_hits / n_lines)
+                sums[modulename] = n_lines, percent, modulename, filename
 
 
         if summary and sums:
@@ -312,6 +308,7 @@ class CoverageResults:
 
     def write_results_file(self, path, lines, lnotab, lines_hit, encoding=None):
         """Return a coverage results file in path."""
+        # ``lnotab`` is a dict of executable lines, or a line number "table"
 
         try:
             outfile = open(path, "w", encoding=encoding)
@@ -330,17 +327,13 @@ class CoverageResults:
                     outfile.write("%5d: " % lines_hit[lineno])
                     n_hits += 1
                     n_lines += 1
-                elif rx_blank.match(line):
-                    outfile.write("       ")
-                else:
-                    # lines preceded by no marks weren't hit
-                    # Highlight them if so indicated, unless the line contains
+                elif lineno in lnotab and not PRAGMA_NOCOVER in line:
+                    # Highlight never-executed lines, unless the line contains
                     # #pragma: NO COVER
-                    if lineno in lnotab and not PRAGMA_NOCOVER in line:
-                        outfile.write(">>>>>> ")
-                        n_lines += 1
-                    else:
-                        outfile.write("       ")
+                    outfile.write(">>>>>> ")
+                    n_lines += 1
+                else:
+                    outfile.write("       ")
                 outfile.write(line.expandtabs(8))
 
         return n_hits, n_lines
diff --git a/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst b/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst
new file mode 100644 (file)
index 0000000..700bc69
--- /dev/null
@@ -0,0 +1,3 @@
+Fix output of cover files for ``trace`` module command-line tool.
+Previously emitted cover files only when ``--missing`` option was used.
+Patch by Michael Selik.
\ No newline at end of file