7
7
from pathlib import Path
8
8
from tempfile import NamedTemporaryFile
9
9
import typing
10
- import warnings
11
10
12
11
from filelock import FileLock
13
12
import mypy .api
@@ -227,6 +226,14 @@ def repr_failure(
227
226
return super ().repr_failure (excinfo )
228
227
229
228
229
+ def _error_severity (error : str ) -> str :
230
+ components = [component .strip () for component in error .split (":" )]
231
+ # The second component is either the line or the severity:
232
+ # demo/note.py:2: note: By default the bodies of untyped functions are not checked
233
+ # demo/sub/conftest.py: error: Duplicate module named "conftest"
234
+ return components [2 ] if components [1 ].isdigit () else components [1 ]
235
+
236
+
230
237
class MypyFileItem (MypyItem ):
231
238
"""A check for Mypy errors in a File."""
232
239
@@ -238,20 +245,15 @@ def runtest(self) -> None:
238
245
error .partition (":" )[2 ].strip ()
239
246
for error in results .abspath_errors .get (abspath , [])
240
247
]
241
- if errors :
242
- if not all (
243
- error .partition (":" )[2 ].partition (":" )[0 ].strip () == "note"
244
- for error in errors
245
- ):
246
- if self .session .config .option .mypy_xfail :
247
- self .add_marker (
248
- pytest .mark .xfail (
249
- raises = MypyError ,
250
- reason = "mypy errors are expected by --mypy-xfail." ,
251
- )
248
+ if errors and not all (_error_severity (error ) == "note" for error in errors ):
249
+ if self .session .config .option .mypy_xfail :
250
+ self .add_marker (
251
+ pytest .mark .xfail (
252
+ raises = MypyError ,
253
+ reason = "mypy errors are expected by --mypy-xfail." ,
252
254
)
253
- raise MypyError ( file_error_formatter ( self , results , errors ) )
254
- warnings . warn ( " \n " + " \n " . join ( errors ), MypyWarning )
255
+ )
256
+ raise MypyError ( file_error_formatter ( self , results , errors ))
255
257
256
258
def reportinfo (self ) -> Tuple [str , None , str ]:
257
259
"""Produce a heading for the test report."""
@@ -371,10 +373,6 @@ class MypyError(Exception):
371
373
"""
372
374
373
375
374
- class MypyWarning (pytest .PytestWarning ):
375
- """A non-failure message regarding the mypy run."""
376
-
377
-
378
376
class MypyControllerPlugin :
379
377
"""A plugin that is not registered on xdist worker processes."""
380
378
@@ -397,9 +395,17 @@ def pytest_terminal_summary(
397
395
if results .stdout :
398
396
if config .option .mypy_xfail :
399
397
terminalreporter .write (results .stdout )
400
- elif results .unmatched_stdout :
401
- color = {"red" : True } if results .status else {"green" : True }
402
- terminalreporter .write_line (results .unmatched_stdout , ** color )
398
+ else :
399
+ for note in (
400
+ unreported_note
401
+ for errors in results .abspath_errors .values ()
402
+ if all (_error_severity (error ) == "note" for error in errors )
403
+ for unreported_note in errors
404
+ ):
405
+ terminalreporter .write_line (note )
406
+ if results .unmatched_stdout :
407
+ color = {"red" : True } if results .status else {"green" : True }
408
+ terminalreporter .write_line (results .unmatched_stdout , ** color )
403
409
if results .stderr :
404
410
terminalreporter .write_line (results .stderr , yellow = True )
405
411
0 commit comments