summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2018-07-15 16:26:48 -0400
committerNed Batchelder <ned@nedbatchelder.com>2018-07-23 19:31:13 -0400
commit7d71b1e052b2adead8c43bbc320582eab4938221 (patch)
tree75a9869f4ba591bc10bc7f3223865de58b7741be
parentc24e594796b860531521be0190fc2f922c092c0e (diff)
downloadpython-coveragepy-git-7d71b1e052b2adead8c43bbc320582eab4938221.tar.gz
Make file operations implicit on constructed filename
-rw-r--r--coverage/data.py26
-rw-r--r--tests/test_concurrency.py4
-rw-r--r--tests/test_data.py76
-rw-r--r--tests/test_debug.py4
-rw-r--r--tests/test_process.py46
-rw-r--r--tests/test_summary.py2
6 files changed, 83 insertions, 75 deletions
diff --git a/coverage/data.py b/coverage/data.py
index 6d30e2ba..23e612a1 100644
--- a/coverage/data.py
+++ b/coverage/data.py
@@ -57,7 +57,10 @@ class CoverageData(object):
names in this API are case-sensitive, even on platforms with
case-insensitive file systems.
- To read a coverage.py data file, use :meth:`read_file`. You can then
+ A data file is associated with the data when the :class:`CoverageData`
+ is created.
+
+ To read a coverage.py data file, use :meth:`read`. You can then
access the line, arc, or file tracer data with :meth:`lines`, :meth:`arcs`,
or :meth:`file_tracer`. Run information is available with
:meth:`run_infos`.
@@ -68,16 +71,15 @@ class CoverageData(object):
most Python containers, you can determine if there is any data at all by
using this object as a boolean value.
-
Most data files will be created by coverage.py itself, but you can use
methods here to create data files if you like. The :meth:`add_lines`,
:meth:`add_arcs`, and :meth:`add_file_tracers` methods add data, in ways
that are convenient for coverage.py. The :meth:`add_run_info` method adds
key-value pairs to the run information.
- To add a file without any measured data, use :meth:`touch_file`.
+ To add a source file without any measured data, use :meth:`touch_file`.
- You write to a named file with :meth:`write_file`.
+ Write the data to its file with :meth:`write`.
You can clear the data in memory with :meth:`erase`. Two data collections
can be combined by using :meth:`update` on one :class:`CoverageData`,
@@ -267,9 +269,13 @@ class CoverageData(object):
__bool__ = __nonzero__
def read(self):
- """Read the coverage data."""
+ """Read the coverage data.
+
+ It is fine for the file to not exist, in which case no data is read.
+
+ """
if os.path.exists(self.filename):
- self.read_file(self.filename)
+ self._read_file(self.filename)
def _read_fileobj(self, file_obj):
"""Read the coverage data from the given file object.
@@ -293,7 +299,7 @@ class CoverageData(object):
self._validate()
- def read_file(self, filename):
+ def _read_file(self, filename):
"""Read the coverage data from `filename` into this object."""
if self._debug and self._debug.should('dataio'):
self._debug.write("Reading data from %r" % (filename,))
@@ -472,7 +478,7 @@ class CoverageData(object):
if suffix:
filename += "." + suffix
- self.write_file(filename)
+ self._write_file(filename)
def _write_fileobj(self, file_obj):
"""Write the coverage data to `file_obj`."""
@@ -496,7 +502,7 @@ class CoverageData(object):
file_obj.write(self._GO_AWAY)
json.dump(file_data, file_obj, separators=(',', ':'))
- def write_file(self, filename):
+ def _write_file(self, filename):
"""Write the coverage data to `filename`."""
if self._debug and self._debug.should('dataio'):
self._debug.write("Writing data to %r" % (filename,))
@@ -635,7 +641,7 @@ class CoverageData(object):
for f in files_to_combine:
new_data = CoverageData(debug=self._debug)
try:
- new_data.read_file(f)
+ new_data._read_file(f)
except CoverageException as exc:
if self._warn:
# The CoverageException has the file name in it, so just
diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py
index 58529ec5..a4f700ed 100644
--- a/tests/test_concurrency.py
+++ b/tests/test_concurrency.py
@@ -235,8 +235,8 @@ class ConcurrencyTest(CoverageTest):
# Read the coverage file and see that try_it.py has all its lines
# executed.
- data = coverage.CoverageData()
- data.read_file(".coverage")
+ data = coverage.CoverageData(".coverage")
+ data.read()
# If the test fails, it's helpful to see this info:
fname = abs_file("try_it.py")
diff --git a/tests/test_data.py b/tests/test_data.py
index 3c0d602b..5deccef0 100644
--- a/tests/test_data.py
+++ b/tests/test_data.py
@@ -430,59 +430,58 @@ class CoverageDataTestInTempDir(DataTestHelpers, CoverageTest):
"""Tests of CoverageData that need a temporary directory to make files."""
def test_read_write_lines(self):
- covdata1 = CoverageData()
+ covdata1 = CoverageData("lines.dat")
covdata1.add_lines(LINES_1)
- covdata1.write_file("lines.dat")
+ covdata1.write()
- covdata2 = CoverageData()
- covdata2.read_file("lines.dat")
+ covdata2 = CoverageData("lines.dat")
+ covdata2.read()
self.assert_lines1_data(covdata2)
def test_read_write_arcs(self):
- covdata1 = CoverageData()
+ covdata1 = CoverageData("arcs.dat")
covdata1.add_arcs(ARCS_3)
- covdata1.write_file("arcs.dat")
+ covdata1.write()
- covdata2 = CoverageData()
- covdata2.read_file("arcs.dat")
+ covdata2 = CoverageData("arcs.dat")
+ covdata2.read()
self.assert_arcs3_data(covdata2)
def test_read_errors(self):
- covdata = CoverageData()
+ msg = r"Couldn't read data from '.*[/\\]{0}': \S+"
- msg = r"Couldn't read data from '{0}': \S+"
self.make_file("xyzzy.dat", "xyzzy")
with self.assertRaisesRegex(CoverageException, msg.format("xyzzy.dat")):
- covdata.read_file("xyzzy.dat")
+ covdata = CoverageData("xyzzy.dat")
+ covdata.read()
+ self.assertFalse(covdata)
self.make_file("empty.dat", "")
with self.assertRaisesRegex(CoverageException, msg.format("empty.dat")):
- covdata.read_file("empty.dat")
-
- with self.assertRaisesRegex(CoverageException, msg.format("nonexistent.dat")):
- covdata.read_file("nonexistent.dat")
+ covdata = CoverageData("empty.dat")
+ covdata.read()
+ self.assertFalse(covdata)
self.make_file("misleading.dat", CoverageData._GO_AWAY + " this isn't JSON")
with self.assertRaisesRegex(CoverageException, msg.format("misleading.dat")):
- covdata.read_file("misleading.dat")
-
- # After all that, no data should be in our CoverageData.
+ covdata = CoverageData("misleading.dat")
+ covdata.read()
self.assertFalse(covdata)
def test_debug_main(self):
- covdata1 = CoverageData()
+ covdata1 = CoverageData(".coverage")
covdata1.add_lines(LINES_1)
- covdata1.write_file(".coverage")
+ covdata1.write()
debug_main([])
- covdata2 = CoverageData()
+ covdata2 = CoverageData("arcs.dat")
covdata2.add_arcs(ARCS_3)
covdata2.add_file_tracers({"y.py": "magic_plugin"})
covdata2.add_run_info(version="v3.14", chunks=["z", "a"])
- covdata2.write_file("arcs.dat")
+ covdata2.write()
- covdata3 = CoverageData()
- covdata3.write_file("empty.dat")
+ covdata3 = CoverageData("empty.dat")
+ covdata3.write()
debug_main(["arcs.dat", "empty.dat"])
expected = {
@@ -725,20 +724,20 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
self.assertEqual(covdata3.file_tracer(template_html), 'html.plugin')
def test_combining_from_different_directories(self):
- covdata1 = CoverageData()
+ covdata1 = CoverageData('cov1/.coverage.1')
covdata1.add_lines(LINES_1)
os.makedirs('cov1')
- covdata1.write_file('cov1/.coverage.1')
+ covdata1.write()
- covdata2 = CoverageData()
+ covdata2 = CoverageData('cov2/.coverage.2')
covdata2.add_lines(LINES_2)
os.makedirs('cov2')
- covdata2.write_file('cov2/.coverage.2')
+ covdata2.write()
# This data won't be included.
- covdata_xxx = CoverageData()
+ covdata_xxx = CoverageData('.coverage.xxx')
covdata_xxx.add_arcs(ARCS_3)
- covdata_xxx.write_file('.coverage.xxx')
+ covdata_xxx.write()
covdata3 = CoverageData()
covdata3.combine_parallel_data(data_paths=['cov1', 'cov2'])
@@ -750,21 +749,24 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
self.assert_exists(".coverage.xxx")
def test_combining_from_files(self):
- covdata1 = CoverageData()
+ covdata1 = CoverageData('cov1/.coverage.1')
covdata1.add_lines(LINES_1)
os.makedirs('cov1')
- covdata1.write_file('cov1/.coverage.1')
+ covdata1.write()
- covdata2 = CoverageData()
+ covdata2 = CoverageData('cov2/.coverage.2')
covdata2.add_lines(LINES_2)
os.makedirs('cov2')
- covdata2.write_file('cov2/.coverage.2')
+ covdata2.write()
# This data won't be included.
- covdata_xxx = CoverageData()
+ covdata_xxx = CoverageData('.coverage.xxx')
covdata_xxx.add_arcs(ARCS_3)
- covdata_xxx.write_file('.coverage.xxx')
- covdata_xxx.write_file('cov2/.coverage.xxx')
+ covdata_xxx.write()
+
+ covdata_2xxx = CoverageData('cov2/.coverage.xxx')
+ covdata_2xxx.add_arcs(ARCS_3)
+ covdata_2xxx.write()
covdata3 = CoverageData()
covdata3.combine_parallel_data(data_paths=['cov1', 'cov2/.coverage.2'])
diff --git a/tests/test_debug.py b/tests/test_debug.py
index 2699ca61..c46e3dae 100644
--- a/tests/test_debug.py
+++ b/tests/test_debug.py
@@ -136,10 +136,10 @@ class DebugTraceTest(CoverageTest):
self.assertEqual(len(real_messages), len(frames))
# The last message should be "Writing data", and the last frame should
- # be write_file in data.py.
+ # be _write_file in data.py.
self.assertRegex(real_messages[-1], r"^\s*\d+\.\w{4}: Writing data")
last_line = out_lines.splitlines()[-1]
- self.assertRegex(last_line, r"\s+write_file : .*coverage[/\\]data.py @\d+$")
+ self.assertRegex(last_line, r"\s+_write_file : .*coverage[/\\]data.py @\d+$")
def test_debug_config(self):
out_lines = self.f1_debug_output(["config"])
diff --git a/tests/test_process.py b/tests/test_process.py
index e022e727..341ad37c 100644
--- a/tests/test_process.py
+++ b/tests/test_process.py
@@ -98,7 +98,7 @@ class ProcessTest(CoverageTest):
# Read the coverage file and see that b_or_c.py has all 8 lines
# executed.
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['b_or_c.py'], 8)
# Running combine again should fail, because there are no parallel data
@@ -109,7 +109,7 @@ class ProcessTest(CoverageTest):
# And the originally combined data is still there.
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['b_or_c.py'], 8)
def test_combine_parallel_data_with_a_corrupt_file(self):
@@ -145,7 +145,7 @@ class ProcessTest(CoverageTest):
# Read the coverage file and see that b_or_c.py has all 8 lines
# executed.
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['b_or_c.py'], 8)
def test_combine_no_usable_files(self):
@@ -179,7 +179,7 @@ class ProcessTest(CoverageTest):
# Read the coverage file and see that b_or_c.py has 6 lines
# executed (we only did b, not c).
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['b_or_c.py'], 6)
def test_combine_parallel_data_in_two_steps(self):
@@ -210,7 +210,7 @@ class ProcessTest(CoverageTest):
# Read the coverage file and see that b_or_c.py has all 8 lines
# executed.
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['b_or_c.py'], 8)
def test_combine_parallel_data_no_append(self):
@@ -242,7 +242,7 @@ class ProcessTest(CoverageTest):
# Read the coverage file and see that b_or_c.py has only 7 lines
# because we didn't keep the data from running b.
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['b_or_c.py'], 7)
def test_append_data(self):
@@ -261,7 +261,7 @@ class ProcessTest(CoverageTest):
# Read the coverage file and see that b_or_c.py has all 8 lines
# executed.
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['b_or_c.py'], 8)
def test_append_data_with_different_file(self):
@@ -284,8 +284,8 @@ class ProcessTest(CoverageTest):
# Read the coverage file and see that b_or_c.py has all 8 lines
# executed.
- data = coverage.CoverageData()
- data.read_file(".mycovdata")
+ data = coverage.CoverageData(".mycovdata")
+ data.read()
self.assertEqual(data.line_counts()['b_or_c.py'], 8)
def test_append_can_create_a_data_file(self):
@@ -299,7 +299,7 @@ class ProcessTest(CoverageTest):
# Read the coverage file and see that b_or_c.py has only 6 lines
# executed.
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['b_or_c.py'], 6)
def test_combine_with_rc(self):
@@ -332,7 +332,7 @@ class ProcessTest(CoverageTest):
# Read the coverage file and see that b_or_c.py has all 8 lines
# executed.
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['b_or_c.py'], 8)
# Reporting should still work even with the .rc file
@@ -386,7 +386,7 @@ class ProcessTest(CoverageTest):
# Read the coverage data file and see that the two different x.py
# files have been combined together.
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
summary = data.line_counts(fullpath=True)
self.assertEqual(len(summary), 1)
actual = os.path.normcase(os.path.abspath(list(summary.keys())[0]))
@@ -549,7 +549,7 @@ class ProcessTest(CoverageTest):
self.assertEqual(self.number_of_data_files(), 1)
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['fork.py'], 9)
def test_warnings_during_reporting(self):
@@ -655,8 +655,8 @@ class ProcessTest(CoverageTest):
self.make_file("simple.py", """print('hello')""")
self.run_command("coverage run simple.py")
- data = CoverageData()
- data.read_file("mydata.dat")
+ data = CoverageData("mydata.dat")
+ data.read()
infos = data.run_infos()
self.assertEqual(len(infos), 1)
expected = u"These are musical notes: ♫𝅗𝅥♩"
@@ -686,7 +686,7 @@ class ProcessTest(CoverageTest):
out = self.run_command("python -m coverage run -L getenv.py")
self.assertEqual(out, "FOOEY == BOO\n")
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
# The actual number of executed lines in os.py when it's
# imported is 120 or so. Just running os.getenv executes
# about 5.
@@ -916,7 +916,7 @@ class ExcepthookTest(CoverageTest):
# Read the coverage file and see that excepthook.py has 7 lines
# executed.
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['excepthook.py'], 7)
def test_excepthook_exit(self):
@@ -1245,9 +1245,9 @@ class ProcessStartupTest(ProcessCoverageMixin, CoverageTest):
# An existing data file should not be read when a subprocess gets
# measured automatically. Create the data file here with bogus data in
# it.
- data = coverage.CoverageData()
+ data = coverage.CoverageData(".mycovdata")
data.add_lines({os.path.abspath('sub.py'): dict.fromkeys(range(100))})
- data.write_file(".mycovdata")
+ data.write()
self.make_file("coverage.ini", """\
[run]
@@ -1261,8 +1261,8 @@ class ProcessStartupTest(ProcessCoverageMixin, CoverageTest):
# Read the data from .coverage
self.assert_exists(".mycovdata")
- data = coverage.CoverageData()
- data.read_file(".mycovdata")
+ data = coverage.CoverageData(".mycovdata")
+ data.read()
self.assertEqual(data.line_counts()['sub.py'], 3)
def test_subprocess_with_pth_files_and_parallel(self): # pragma: no metacov
@@ -1286,7 +1286,7 @@ class ProcessStartupTest(ProcessCoverageMixin, CoverageTest):
# assert that the combined .coverage data file is correct
self.assert_exists(".coverage")
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
self.assertEqual(data.line_counts()['sub.py'], 3)
# assert that there are *no* extra data files left over after a combine
@@ -1376,7 +1376,7 @@ class ProcessStartupWithSourceTest(ProcessCoverageMixin, CoverageTest):
# Read the data from .coverage
self.assert_exists(".coverage")
data = coverage.CoverageData()
- data.read_file(".coverage")
+ data.read()
summary = data.line_counts()
print(summary)
self.assertEqual(summary[source + '.py'], 3)
diff --git a/tests/test_summary.py b/tests/test_summary.py
index b2895370..980fd3d4 100644
--- a/tests/test_summary.py
+++ b/tests/test_summary.py
@@ -161,7 +161,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
# Read the data written, to see that the right files have been omitted from running.
covdata = CoverageData()
- covdata.read_file(".coverage")
+ covdata.read()
files = [os.path.basename(p) for p in covdata.measured_files()]
self.assertIn("covmod1.py", files)
self.assertNotIn("covmodzip1.py", files)