diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2021-10-09 16:41:59 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2021-10-09 16:41:59 -0400 |
commit | 498b1484e466588a22cef520095f1fd0ed8b8ff8 (patch) | |
tree | 84979ae5f419d8632ba898d8464dc142778e9f1c | |
parent | 4d55ada1bdca638b0fd12e887fb0faaa574dee8d (diff) | |
download | python-coveragepy-git-498b1484e466588a22cef520095f1fd0ed8b8ff8.tar.gz |
fix: contexts_by_lineno now returns a true dict
-rw-r--r-- | CHANGES.rst | 4 | ||||
-rw-r--r-- | coverage/html.py | 2 | ||||
-rw-r--r-- | coverage/jsonreport.py | 6 | ||||
-rw-r--r-- | coverage/sqldata.py | 18 | ||||
-rw-r--r-- | tests/test_data.py | 27 |
5 files changed, 40 insertions, 17 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index b84ee0fa..7e5f7782 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -22,7 +22,9 @@ This list is detailed and covers changes in each pre-release version. Unreleased ---------- -Nothing yet. +- The :meth:`.CoverageData.contexts_by_lineno` method was documented to return + a dict, but was returning a defaultdict. Now it returns a plain dict. It + also no longer returns negative numbered keys. .. _changes_601: diff --git a/coverage/html.py b/coverage/html.py index 208554c8..b095343e 100644 --- a/coverage/html.py +++ b/coverage/html.py @@ -123,7 +123,7 @@ class HtmlDataGeneration: contexts = contexts_label = None context_list = None if category and self.config.show_contexts: - contexts = sorted(c or self.EMPTY for c in contexts_by_lineno[lineno]) + contexts = sorted(c or self.EMPTY for c in contexts_by_lineno.get(lineno, ())) if contexts == [self.EMPTY]: contexts_label = self.EMPTY else: diff --git a/coverage/jsonreport.py b/coverage/jsonreport.py index b22ab10b..daebca11 100644 --- a/coverage/jsonreport.py +++ b/coverage/jsonreport.py @@ -88,12 +88,10 @@ class JsonReporter: 'executed_lines': sorted(analysis.executed), 'summary': summary, 'missing_lines': sorted(analysis.missing), - 'excluded_lines': sorted(analysis.excluded) + 'excluded_lines': sorted(analysis.excluded), } if self.config.json_show_contexts: - reported_file['contexts'] = analysis.data.contexts_by_lineno( - analysis.filename, - ) + reported_file['contexts'] = analysis.data.contexts_by_lineno(analysis.filename) if coverage_data.has_arcs(): reported_file['summary'].update({ 'num_branches': nums.n_branches, diff --git a/coverage/sqldata.py b/coverage/sqldata.py index 412a9eb7..108a25ef 100644 --- a/coverage/sqldata.py +++ b/coverage/sqldata.py @@ -942,12 +942,13 @@ class CoverageData(SimpleReprMixin): .. versionadded:: 5.0 """ - lineno_contexts_map = collections.defaultdict(list) self._start_using() with self._connect() as con: file_id = self._file_id(filename) if file_id is None: - return lineno_contexts_map + return {} + + lineno_contexts_map = collections.defaultdict(set) if self.has_arcs(): query = ( "select arc.fromno, arc.tono, context.context " + @@ -960,10 +961,10 @@ class CoverageData(SimpleReprMixin): query += " and arc.context_id in (" + ids_array + ")" data += self._query_context_ids for fromno, tono, context in con.execute(query, data): - if context not in lineno_contexts_map[fromno]: - lineno_contexts_map[fromno].append(context) - if context not in lineno_contexts_map[tono]: - lineno_contexts_map[tono].append(context) + if fromno > 0: + lineno_contexts_map[fromno].add(context) + if tono > 0: + lineno_contexts_map[tono].add(context) else: query = ( "select l.numbits, c.context from line_bits l, context c " + @@ -977,8 +978,9 @@ class CoverageData(SimpleReprMixin): data += self._query_context_ids for numbits, context in con.execute(query, data): for lineno in numbits_to_nums(numbits): - lineno_contexts_map[lineno].append(context) - return lineno_contexts_map + lineno_contexts_map[lineno].add(context) + + return {lineno: list(contexts) for lineno, contexts in lineno_contexts_map.items()} @classmethod def sys_info(cls): diff --git a/tests/test_data.py b/tests/test_data.py index 2d3f164c..80cd9bc2 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -206,7 +206,8 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata = CoverageData() covdata.set_context('test_a') covdata.add_lines(LINES_1) - assert covdata.contexts_by_lineno('a.py') == {1: ['test_a'], 2: ['test_a']} + expected = {1: ['test_a'], 2: ['test_a']} + assert covdata.contexts_by_lineno('a.py') == expected @pytest.mark.parametrize("lines", [LINES_1, dicts_from_sets(LINES_1)]) def test_no_duplicate_lines(self, lines): @@ -249,13 +250,33 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata = CoverageData() covdata.set_context('test_x') covdata.add_arcs(ARCS_3) - expected = {-1: ['test_x'], 1: ['test_x'], 2: ['test_x'], 3: ['test_x']} - assert expected == covdata.contexts_by_lineno('x.py') + expected = {1: ['test_x'], 2: ['test_x'], 3: ['test_x']} + assert covdata.contexts_by_lineno('x.py') == expected def test_contexts_by_lineno_with_unknown_file(self): covdata = CoverageData() + covdata.set_context('test_x') + covdata.add_arcs(ARCS_3) assert covdata.contexts_by_lineno('xyz.py') == {} + def test_context_by_lineno_with_query_contexts_with_lines(self): + covdata = CoverageData() + covdata.set_context("test_1") + covdata.add_lines(LINES_1) + covdata.set_context("test_2") + covdata.add_lines(LINES_2) + covdata.set_query_context("test_1") + assert covdata.contexts_by_lineno("a.py") == dict.fromkeys([1,2], ["test_1"]) + + def test_context_by_lineno_with_query_contexts_with_arcs(self): + covdata = CoverageData() + covdata.set_context("test_1") + covdata.add_arcs(ARCS_3) + covdata.set_context("test_2") + covdata.add_arcs(ARCS_4) + covdata.set_query_context("test_1") + assert covdata.contexts_by_lineno("x.py") == dict.fromkeys([1,2,3], ["test_1"]) + def test_file_tracer_name(self): covdata = CoverageData() covdata.add_lines({ |