@@ -89,6 +89,11 @@ def pytest_addoption(parser: pytest.Parser) -> None:
8989 action = "store_true" ,
9090 help = "ignore mypy's exit status" ,
9191 )
92+ group .addoption (
93+ "--mypy-xfail" ,
94+ action = "store_true" ,
95+ help = "xfail mypy errors and report them in the summary instead" ,
96+ )
9297
9398
9499def _xdist_worker (config : pytest .Config ) -> Dict [str , Any ]:
@@ -170,6 +175,7 @@ def pytest_collect_file(
170175 parent .config .option .mypy_config_file ,
171176 parent .config .option .mypy_ignore_missing_imports ,
172177 parent .config .option .mypy_no_status_check ,
178+ parent .config .option .mypy_xfail ,
173179 ],
174180 ):
175181 # Do not create MypyFile instance for a .py file if a
@@ -234,6 +240,14 @@ def runtest(self) -> None:
234240 error .partition (":" )[2 ].partition (":" )[0 ].strip () == "note"
235241 for error in errors
236242 ):
243+ if self .session .config .option .mypy_xfail :
244+ self .add_marker (
245+ pytest .mark .xfail (
246+ raises = MypyError ,
247+ reason = "The mypy errors in this file"
248+ " were xfailed by --mypy-xfail." ,
249+ )
250+ )
237251 raise MypyError (file_error_formatter (self , results , errors ))
238252 warnings .warn ("\n " + "\n " .join (errors ), MypyWarning )
239253
@@ -253,6 +267,14 @@ def runtest(self) -> None:
253267 """Raise a MypyError if mypy exited with a non-zero status."""
254268 results = MypyResults .from_session (self .session )
255269 if results .status :
270+ if self .session .config .option .mypy_xfail :
271+ self .add_marker (
272+ pytest .mark .xfail (
273+ raises = MypyError ,
274+ reason = f"mypy's non-zero exit status ({ results .status } )"
275+ " was xfailed by --mypy-xfail." ,
276+ )
277+ )
256278 raise MypyError (f"mypy exited with status { results .status } ." )
257279
258280
@@ -366,9 +388,11 @@ def pytest_terminal_summary(
366388 except FileNotFoundError :
367389 # No MypyItems executed.
368390 return
369- if results .unmatched_stdout or results .stderr :
391+ if config . option . mypy_xfail or results .unmatched_stdout or results .stderr :
370392 terminalreporter .section (terminal_summary_title )
371- if results .unmatched_stdout :
393+ if config .option .mypy_xfail :
394+ terminalreporter .write (results .stdout )
395+ elif results .unmatched_stdout :
372396 color = {"red" : True } if results .status else {"green" : True }
373397 terminalreporter .write_line (results .unmatched_stdout , ** color )
374398 if results .stderr :
0 commit comments