Skip to content

Commit f132c3a

Browse files
committed
Enable branch code coverage
1 parent 82c41fb commit f132c3a

File tree

3 files changed

+77
-7
lines changed

3 files changed

+77
-7
lines changed

src/pytest_mypy.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,7 @@ def runtest(self):
208208
for error in errors
209209
):
210210
raise MypyError(file_error_formatter(self, results, errors))
211-
# This line cannot be easily covered on mypy < 0.990:
212-
warnings.warn("\n" + "\n".join(errors), MypyWarning) # pragma: no cover
211+
warnings.warn("\n" + "\n".join(errors), MypyWarning)
213212

214213
def reportinfo(self):
215214
"""Produce a heading for the test report."""

tests/test_pytest_mypy.py

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import pexpect
77
import pytest
88

9+
import pytest_mypy
10+
911

1012
MYPY_VERSION = Version(mypy.version.__version__)
1113
PYTEST_VERSION = Version(pytest.__version__)
@@ -98,7 +100,7 @@ def pyfunc(x: int) -> str:
98100
assert result.ret != 0
99101

100102

101-
def test_mypy_annotation_unchecked(testdir, xdist_args):
103+
def test_mypy_annotation_unchecked(testdir, xdist_args, tmp_path, monkeypatch):
102104
"""Verify that annotation-unchecked warnings do not manifest as an error."""
103105
testdir.makepyfile(
104106
"""
@@ -107,16 +109,37 @@ def pyfunc(x):
107109
return x * y
108110
""",
109111
)
112+
min_mypy_version = Version("0.990")
113+
if MYPY_VERSION < min_mypy_version:
114+
# mypy doesn't emit annotation-unchecked warnings until 0.990:
115+
fake_mypy_path = tmp_path / "mypy"
116+
fake_mypy_path.mkdir()
117+
(fake_mypy_path / "__init__.py").touch()
118+
(fake_mypy_path / "api.py").write_text(
119+
textwrap.dedent(
120+
"""
121+
def run(*args, **kwargs):
122+
return (
123+
"test_mypy_annotation_unchecked.py:2:"
124+
" note: By default the bodies of untyped functions"
125+
" are not checked, consider using --check-untyped-defs"
126+
" [annotation-unchecked]\\nSuccess: no issues found in"
127+
" 1 source file\\n",
128+
"",
129+
0,
130+
)
131+
"""
132+
)
133+
)
134+
monkeypatch.setenv("PYTHONPATH", str(tmp_path))
110135
result = testdir.runpytest_subprocess(*xdist_args)
111136
result.assert_outcomes()
112137
result = testdir.runpytest_subprocess("--mypy", *xdist_args)
113138
mypy_file_checks = 1
114139
mypy_status_check = 1
115140
mypy_checks = mypy_file_checks + mypy_status_check
116141
outcomes = {"passed": mypy_checks}
117-
# mypy doesn't emit annotation-unchecked warnings until 0.990:
118-
min_mypy_version = Version("0.990")
119-
if MYPY_VERSION >= min_mypy_version and PYTEST_VERSION >= Version("7.0"):
142+
if PYTEST_VERSION >= Version("7.0"):
120143
# assert_outcomes does not support `warnings` until 7.x.
121144
outcomes["warnings"] = 1
122145
result.assert_outcomes(**outcomes)
@@ -554,3 +577,51 @@ def test_mypy_item_collect(request):
554577
mypy_status_check = 1
555578
result.assert_outcomes(passed=test_count + mypy_file_checks + mypy_status_check)
556579
assert result.ret == 0
580+
581+
582+
@pytest.mark.xfail(
583+
MYPY_VERSION < Version("0.750"),
584+
reason="https://github.com/python/mypy/issues/7800",
585+
)
586+
def test_mypy_results_from_mypy_with_opts():
587+
"""MypyResults.from_mypy respects passed options."""
588+
mypy_results = pytest_mypy.MypyResults.from_mypy([], opts=["--version"])
589+
assert mypy_results.status == 0
590+
assert mypy_results.abspath_errors == {}
591+
assert str(MYPY_VERSION) in mypy_results.stdout
592+
593+
594+
def test_mypy_no_output(testdir, xdist_args):
595+
"""No terminal summary is shown if there is no output from mypy."""
596+
# Pytest didn't add type annotations until 6.0.
597+
type_ignore = "# type: ignore" if PYTEST_VERSION < Version("6.0") else ""
598+
testdir.makepyfile(
599+
conftest=f"""
600+
import tempfile
601+
602+
import pytest {type_ignore}
603+
604+
@pytest.hookimpl(hookwrapper=True)
605+
def pytest_terminal_summary(config):
606+
pytest_mypy = config.pluginmanager.getplugin("mypy")
607+
with open(config._mypy_results_path, mode="r") as results_f:
608+
results = pytest_mypy.MypyResults.load(results_f)
609+
with open(config._mypy_results_path, mode="w") as results_f:
610+
pytest_mypy.MypyResults(
611+
opts=results.opts,
612+
stdout=results.stdout,
613+
stderr="",
614+
status=results.status,
615+
abspath_errors=results.abspath_errors,
616+
unmatched_stdout="",
617+
).dump(results_f)
618+
yield
619+
""",
620+
)
621+
result = testdir.runpytest_subprocess("--mypy", *xdist_args)
622+
mypy_file_checks = 1
623+
mypy_status_check = 1
624+
mypy_checks = mypy_file_checks + mypy_status_check
625+
result.assert_outcomes(passed=mypy_checks)
626+
assert result.ret == 0
627+
assert "= mypy =" not in str(result.stdout)

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ deps =
4242
pytest-randomly ~= 3.4
4343
pytest-xdist ~= 1.34
4444

45-
commands = pytest -p no:mypy {posargs:--cov pytest_mypy --cov-fail-under 100 --cov-report term-missing -n auto}
45+
commands = pytest -p no:mypy {posargs:--cov pytest_mypy --cov-branch --cov-fail-under 100 --cov-report term-missing -n auto}
4646

4747
[pytest]
4848
testpaths = tests

0 commit comments

Comments
 (0)