diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2018-07-15 16:26:48 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2018-07-23 19:31:13 -0400 |
commit | 7d71b1e052b2adead8c43bbc320582eab4938221 (patch) | |
tree | 75a9869f4ba591bc10bc7f3223865de58b7741be | |
parent | c24e594796b860531521be0190fc2f922c092c0e (diff) | |
download | python-coveragepy-git-7d71b1e052b2adead8c43bbc320582eab4938221.tar.gz |
Make file operations implicit on constructed filename
-rw-r--r-- | coverage/data.py | 26 | ||||
-rw-r--r-- | tests/test_concurrency.py | 4 | ||||
-rw-r--r-- | tests/test_data.py | 76 | ||||
-rw-r--r-- | tests/test_debug.py | 4 | ||||
-rw-r--r-- | tests/test_process.py | 46 | ||||
-rw-r--r-- | tests/test_summary.py | 2 |
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) |