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__ )
@@ -100,7 +102,7 @@ def pyfunc(x: int) -> str:
100
102
assert "_mypy_results_path" not in result .stderr .str ()
101
103
102
104
103
- def test_mypy_annotation_unchecked (testdir , xdist_args ):
105
+ def test_mypy_annotation_unchecked (testdir , xdist_args , tmp_path , monkeypatch ):
104
106
"""Verify that annotation-unchecked warnings do not manifest as an error."""
105
107
testdir .makepyfile (
106
108
"""
@@ -109,6 +111,29 @@ def pyfunc(x):
109
111
return x * y
110
112
""" ,
111
113
)
114
+ min_mypy_version = Version ("0.990" )
115
+ if MYPY_VERSION < min_mypy_version :
116
+ # mypy doesn't emit annotation-unchecked warnings until 0.990:
117
+ fake_mypy_path = tmp_path / "mypy"
118
+ fake_mypy_path .mkdir ()
119
+ (fake_mypy_path / "__init__.py" ).touch ()
120
+ (fake_mypy_path / "api.py" ).write_text (
121
+ textwrap .dedent (
122
+ """
123
+ def run(*args, **kwargs):
124
+ return (
125
+ "test_mypy_annotation_unchecked.py:2:"
126
+ " note: By default the bodies of untyped functions"
127
+ " are not checked, consider using --check-untyped-defs"
128
+ " [annotation-unchecked]\\ nSuccess: no issues found in"
129
+ " 1 source file\\ n",
130
+ "",
131
+ 0,
132
+ )
133
+ """
134
+ )
135
+ )
136
+ monkeypatch .setenv ("PYTHONPATH" , str (tmp_path ))
112
137
result = testdir .runpytest_subprocess (* xdist_args )
113
138
result .assert_outcomes ()
114
139
result = testdir .runpytest_subprocess ("--mypy" , * xdist_args )
@@ -552,3 +577,59 @@ def test_mypy_item_collect(request):
552
577
mypy_status_check = 1
553
578
result .assert_outcomes (passed = test_count + mypy_file_checks + mypy_status_check )
554
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
+ type_ignore = (
598
+ "# type: ignore"
599
+ if (
600
+ PYTEST_VERSION
601
+ < Version ("6.0" ) # Pytest didn't add type annotations until 6.0.
602
+ or MYPY_VERSION < Version ("0.710" )
603
+ )
604
+ else ""
605
+ )
606
+ testdir .makepyfile (
607
+ conftest = f"""
608
+ import tempfile
609
+
610
+ import pytest { type_ignore }
611
+
612
+ @pytest.hookimpl(hookwrapper=True)
613
+ def pytest_terminal_summary(config):
614
+ pytest_mypy = config.pluginmanager.getplugin("mypy")
615
+ with open(config._mypy_results_path, mode="r") as results_f:
616
+ results = pytest_mypy.MypyResults.load(results_f)
617
+ with open(config._mypy_results_path, mode="w") as results_f:
618
+ pytest_mypy.MypyResults(
619
+ opts=results.opts,
620
+ stdout=results.stdout,
621
+ stderr="",
622
+ status=results.status,
623
+ abspath_errors=results.abspath_errors,
624
+ unmatched_stdout="",
625
+ ).dump(results_f)
626
+ yield
627
+ """ ,
628
+ )
629
+ result = testdir .runpytest_subprocess ("--mypy" , * xdist_args )
630
+ mypy_file_checks = 1
631
+ mypy_status_check = 1
632
+ mypy_checks = mypy_file_checks + mypy_status_check
633
+ result .assert_outcomes (passed = mypy_checks )
634
+ assert result .ret == 0
635
+ assert "= mypy =" not in str (result .stdout )
0 commit comments