66import pexpect
77import pytest
88
9+ import pytest_mypy
10+
911
1012MYPY_VERSION = Version (mypy .version .__version__ )
1113PYTEST_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,59 @@ 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+ 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