Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions Lib/test/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
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
Expand Down Expand Up @@ -365,6 +366,46 @@ def test_ignored(self):
# 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):
Expand Down
39 changes: 16 additions & 23 deletions Lib/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ def _unsettrace():

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)
Expand Down Expand Up @@ -278,16 +275,15 @@ def write_results(self, show_missing=True, summary=False, coverdir=None):
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:
Expand All @@ -306,6 +302,7 @@ def write_results(self, show_missing=True, summary=False, coverdir=None):

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)
Expand All @@ -324,17 +321,13 @@ def write_results_file(self, path, lines, lnotab, lines_hit, encoding=None):
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
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst
Original file line number Diff line number Diff line change
@@ -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.