summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2022-12-31 19:36:23 -0500
committerNed Batchelder <ned@nedbatchelder.com>2022-12-31 20:39:09 -0500
commit586726322069bab62f33dccab70101ca76f595c2 (patch)
tree5b11f2e5c1a4e3801974c3d294abf604250bcac6
parente3c523c98cbc9ecdd37e36da19848ca9d0aef4a3 (diff)
downloadpython-coveragepy-git-586726322069bab62f33dccab70101ca76f595c2.tar.gz
mypy: add annotate.py and jsonreport.py
-rw-r--r--coverage/annotate.py18
-rw-r--r--coverage/jsonreport.py25
-rw-r--r--coverage/report.py2
-rw-r--r--coverage/sqldata.py2
-rw-r--r--tox.ini4
5 files changed, 36 insertions, 15 deletions
diff --git a/coverage/annotate.py b/coverage/annotate.py
index 07ff644d..c92c29b7 100644
--- a/coverage/annotate.py
+++ b/coverage/annotate.py
@@ -3,12 +3,22 @@
"""Source file annotation for coverage.py."""
+from __future__ import annotations
+
import os
import re
+from typing import Iterable, Optional, TYPE_CHECKING
+
from coverage.files import flat_rootname
from coverage.misc import ensure_dir, isolate_module
+from coverage.plugin import FileReporter
from coverage.report import get_analysis_to_report
+from coverage.results import Analysis
+from coverage.types import TMorf
+
+if TYPE_CHECKING:
+ from coverage import Coverage
os = isolate_module(os)
@@ -35,15 +45,15 @@ class AnnotateReporter:
"""
- def __init__(self, coverage):
+ def __init__(self, coverage: Coverage) -> None:
self.coverage = coverage
self.config = self.coverage.config
- self.directory = None
+ self.directory: Optional[str] = None
blank_re = re.compile(r"\s*(#|$)")
else_re = re.compile(r"\s*else\s*:\s*(#|$)")
- def report(self, morfs, directory=None):
+ def report(self, morfs: Optional[Iterable[TMorf]], directory: Optional[str]=None) -> None:
"""Run the report.
See `coverage.report()` for arguments.
@@ -54,7 +64,7 @@ class AnnotateReporter:
for fr, analysis in get_analysis_to_report(self.coverage, morfs):
self.annotate_file(fr, analysis)
- def annotate_file(self, fr, analysis):
+ def annotate_file(self, fr: FileReporter, analysis: Analysis) -> None:
"""Annotate a single file.
`fr` is the FileReporter for the file to annotate.
diff --git a/coverage/jsonreport.py b/coverage/jsonreport.py
index 3afae2cc..7ee1fb99 100644
--- a/coverage/jsonreport.py
+++ b/coverage/jsonreport.py
@@ -3,13 +3,22 @@
"""Json reporting for coverage.py"""
+from __future__ import annotations
+
import datetime
import json
import sys
+from typing import Any, Dict, IO, Iterable, List, Optional, Tuple, TYPE_CHECKING
+
from coverage import __version__
from coverage.report import get_analysis_to_report
-from coverage.results import Numbers
+from coverage.results import Analysis, Numbers
+from coverage.types import TMorf, TLineNo
+
+if TYPE_CHECKING:
+ from coverage import Coverage
+ from coverage.data import CoverageData
class JsonReporter:
@@ -17,13 +26,13 @@ class JsonReporter:
report_type = "JSON report"
- def __init__(self, coverage):
+ def __init__(self, coverage: Coverage) -> None:
self.coverage = coverage
self.config = self.coverage.config
self.total = Numbers(self.config.precision)
- self.report_data = {}
+ self.report_data: Dict[str, Any] = {}
- def report(self, morfs, outfile=None):
+ def report(self, morfs: Optional[Iterable[TMorf]], outfile: IO[str]) -> float:
"""Generate a json report for `morfs`.
`morfs` is a list of modules or file names.
@@ -75,7 +84,7 @@ class JsonReporter:
return self.total.n_statements and self.total.pc_covered
- def report_one_file(self, coverage_data, analysis):
+ def report_one_file(self, coverage_data: CoverageData, analysis: Analysis) -> Dict[str, Any]:
"""Extract the relevant report data for a single file."""
nums = analysis.numbers
self.total += nums
@@ -96,7 +105,7 @@ class JsonReporter:
if self.config.json_show_contexts:
reported_file['contexts'] = analysis.data.contexts_by_lineno(analysis.filename)
if coverage_data.has_arcs():
- reported_file['summary'].update({
+ summary.update({
'num_branches': nums.n_branches,
'num_partial_branches': nums.n_partial_branches,
'covered_branches': nums.n_executed_branches,
@@ -111,7 +120,9 @@ class JsonReporter:
return reported_file
-def _convert_branch_arcs(branch_arcs):
+def _convert_branch_arcs(
+ branch_arcs: Dict[TLineNo, List[TLineNo]],
+) -> Iterable[Tuple[TLineNo, TLineNo]]:
"""Convert branch arcs to a list of two-element tuples."""
for source, targets in branch_arcs.items():
for target in targets:
diff --git a/coverage/report.py b/coverage/report.py
index 549ab307..74ae1817 100644
--- a/coverage/report.py
+++ b/coverage/report.py
@@ -71,7 +71,7 @@ def render_report(
def get_analysis_to_report(
coverage: Coverage,
- morfs: Iterable[TMorf]
+ morfs: Optional[Iterable[TMorf]],
) -> Iterator[Tuple[FileReporter, Analysis]]:
"""Get the files to report on.
diff --git a/coverage/sqldata.py b/coverage/sqldata.py
index d9f8ceaf..e7e941a6 100644
--- a/coverage/sqldata.py
+++ b/coverage/sqldata.py
@@ -884,7 +884,7 @@ class CoverageData(AutoReprMixin):
with con.execute("select id from context where context = ?", (context,)) as cur:
self._query_context_ids = [row[0] for row in cur.fetchall()]
- def set_query_contexts(self, contexts: Sequence[str]) -> None:
+ def set_query_contexts(self, contexts: Optional[Sequence[str]]) -> None:
"""Set a number of contexts for subsequent querying.
The next :meth:`lines`, :meth:`arcs`, or :meth:`contexts_by_lineno`
diff --git a/tox.ini b/tox.ini
index 8d9c9891..36237b02 100644
--- a/tox.ini
+++ b/tox.ini
@@ -95,9 +95,9 @@ deps =
setenv =
{[testenv]setenv}
- C__B=coverage/__init__.py coverage/__main__.py coverage/bytecode.py
+ C__B=coverage/__init__.py coverage/__main__.py coverage/annotate.py coverage/bytecode.py
C_CE=coverage/config.py coverage/context.py coverage/control.py coverage/data.py coverage/disposition.py coverage/exceptions.py
- C_FN=coverage/files.py coverage/inorout.py coverage/multiproc.py coverage/numbits.py
+ C_FN=coverage/files.py coverage/inorout.py coverage/jsonreport.py coverage/multiproc.py coverage/numbits.py
C_OP=coverage/parser.py coverage/phystokens.py coverage/plugin.py coverage/python.py
C_QZ=coverage/report.py coverage/results.py coverage/sqldata.py coverage/tomlconfig.py coverage/types.py coverage/version.py
T_AN=tests/test_api.py tests/goldtest.py tests/helpers.py tests/test_html.py