6
6
import pexpect
7
7
import pytest
8
8
9
+ import pytest_mypy
10
+
9
11
10
12
MYPY_VERSION = Version (mypy .version .__version__ )
11
13
PYTEST_VERSION = Version (pytest .__version__ )
@@ -98,7 +100,7 @@ def pyfunc(x: int) -> str:
98
100
assert result .ret != 0
99
101
100
102
101
- def test_mypy_annotation_unchecked (testdir , xdist_args ):
103
+ def test_mypy_annotation_unchecked (testdir , xdist_args , tmp_path , monkeypatch ):
102
104
"""Verify that annotation-unchecked warnings do not manifest as an error."""
103
105
testdir .makepyfile (
104
106
"""
@@ -107,16 +109,37 @@ def pyfunc(x):
107
109
return x * y
108
110
""" ,
109
111
)
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 ))
110
135
result = testdir .runpytest_subprocess (* xdist_args )
111
136
result .assert_outcomes ()
112
137
result = testdir .runpytest_subprocess ("--mypy" , * xdist_args )
113
138
mypy_file_checks = 1
114
139
mypy_status_check = 1
115
140
mypy_checks = mypy_file_checks + mypy_status_check
116
141
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" ):
120
143
# assert_outcomes does not support `warnings` until 7.x.
121
144
outcomes ["warnings" ] = 1
122
145
result .assert_outcomes (** outcomes )
@@ -554,3 +577,52 @@ def test_mypy_item_collect(request):
554
577
mypy_status_check = 1
555
578
result .assert_outcomes (passed = test_count + mypy_file_checks + mypy_status_check )
556
579
assert result .ret == 0
580
+
581
+
582
+ @pytest .mark .xfail (
583
+ MYPY_VERSION < Version ("0.750" ),
584
+ raises = AssertionError ,
585
+ reason = "https://github.com/python/mypy/issues/7800" ,
586
+ )
587
+ def test_mypy_results_from_mypy_with_opts ():
588
+ """MypyResults.from_mypy respects passed options."""
589
+ mypy_results = pytest_mypy .MypyResults .from_mypy ([], opts = ["--version" ])
590
+ assert mypy_results .status == 0
591
+ assert mypy_results .abspath_errors == {}
592
+ assert str (MYPY_VERSION ) in mypy_results .stdout
593
+
594
+
595
+ def test_mypy_no_output (testdir , xdist_args ):
596
+ """No terminal summary is shown if there is no output from mypy."""
597
+ # Pytest didn't add type annotations until 6.0.
598
+ type_ignore = "# type: ignore" if PYTEST_VERSION < Version ("6.0" ) else ""
599
+ testdir .makepyfile (
600
+ conftest = f"""
601
+ import tempfile
602
+
603
+ import pytest { type_ignore }
604
+
605
+ @pytest.hookimpl(hookwrapper=True)
606
+ def pytest_terminal_summary(config):
607
+ pytest_mypy = config.pluginmanager.getplugin("mypy")
608
+ with open(config._mypy_results_path, mode="r") as results_f:
609
+ results = pytest_mypy.MypyResults.load(results_f)
610
+ with open(config._mypy_results_path, mode="w") as results_f:
611
+ pytest_mypy.MypyResults(
612
+ opts=results.opts,
613
+ stdout=results.stdout,
614
+ stderr="",
615
+ status=results.status,
616
+ abspath_errors=results.abspath_errors,
617
+ unmatched_stdout="",
618
+ ).dump(results_f)
619
+ yield
620
+ """ ,
621
+ )
622
+ result = testdir .runpytest_subprocess ("--mypy" , * xdist_args )
623
+ mypy_file_checks = 1
624
+ mypy_status_check = 1
625
+ mypy_checks = mypy_file_checks + mypy_status_check
626
+ result .assert_outcomes (passed = mypy_checks )
627
+ assert result .ret == 0
628
+ assert "= mypy =" not in str (result .stdout )
0 commit comments