22
33from __future__ import annotations
44
5+ from collections .abc import Iterator
56from dataclasses import dataclass
67import json
78from pathlib import Path
1314import pytest
1415
1516if typing .TYPE_CHECKING : # pragma: no cover
16- from typing import (
17- Any ,
18- Dict ,
19- IO ,
20- Iterator ,
21- List ,
22- Optional ,
23- Tuple ,
24- Union ,
25- )
2617
2718 # https://github.com/pytest-dev/pytest/issues/7469
2819 from _pytest ._code .code import TerminalRepr
@@ -49,7 +40,7 @@ def serialized(self) -> str:
4940
5041
5142item_marker = "mypy"
52- mypy_argv : List [str ] = []
43+ mypy_argv : list [str ] = []
5344nodeid_name = "mypy"
5445stash_key = {
5546 "config" : pytest .StashKey [MypyConfigStash ](),
@@ -68,7 +59,7 @@ def default_test_name_formatter(*, item: MypyFileItem) -> str:
6859def default_file_error_formatter (
6960 item : MypyItem ,
7061 results : MypyResults ,
71- lines : List [str ],
62+ lines : list [str ],
7263) -> str :
7364 """Create a string to be displayed when mypy finds errors in a file."""
7465 if item .config .option .mypy_report_style == "mypy" :
@@ -116,7 +107,7 @@ def pytest_addoption(parser: pytest.Parser) -> None:
116107 )
117108
118109
119- def _xdist_worker (config : pytest .Config ) -> Dict [str , Any ]:
110+ def _xdist_worker (config : pytest .Config ) -> dict [str , typing . Any ]:
120111 try :
121112 # xdist.remote defines the workerinput attribute in worker processes.
122113 return {"input" : config .workerinput } # type: ignore[attr-defined]
@@ -195,7 +186,7 @@ def pytest_collect_file(
195186 self ,
196187 file_path : Path ,
197188 parent : pytest .Collector ,
198- ) -> Optional [ MypyFile ] :
189+ ) -> MypyFile | None :
199190 """Create a MypyFileItem for every file mypy should run on."""
200191 if file_path .suffix in {".py" , ".pyi" }:
201192 # Do not create MypyFile instance for a .py file if a
@@ -230,15 +221,15 @@ def collect(self) -> Iterator[MypyItem]:
230221class MypyItem (pytest .Item ):
231222 """A Mypy-related test Item."""
232223
233- def __init__ (self , * args : Any , ** kwargs : Any ):
224+ def __init__ (self , * args : typing . Any , ** kwargs : typing . Any ):
234225 super ().__init__ (* args , ** kwargs )
235226 self .add_marker (item_marker )
236227
237228 def repr_failure (
238229 self ,
239230 excinfo : pytest .ExceptionInfo [BaseException ],
240- style : Optional [ str ] = None ,
241- ) -> Union [ str , TerminalRepr ] :
231+ style : str | None = None ,
232+ ) -> str | TerminalRepr :
242233 """
243234 Unwrap mypy errors so we get a clean error message without the
244235 full exception repr.
@@ -248,7 +239,7 @@ def repr_failure(
248239 return super ().repr_failure (excinfo )
249240
250241
251- def _error_severity (line : str ) -> Optional [ str ] :
242+ def _error_severity (line : str ) -> str | None :
252243 components = [component .strip () for component in line .split (":" , 3 )]
253244 if len (components ) < 2 :
254245 return None
@@ -275,7 +266,7 @@ def runtest(self) -> None:
275266 )
276267 raise MypyError (file_error_formatter (self , results , lines ))
277268
278- def reportinfo (self ) -> Tuple [Path , None , str ]:
269+ def reportinfo (self ) -> tuple [Path , None , str ]:
279270 """Produce a heading for the test report."""
280271 return (self .path , None , test_name_formatter (item = self ))
281272
@@ -305,14 +296,14 @@ class MypyResults:
305296
306297 _encoding = "utf-8"
307298
308- opts : List [str ]
309- args : List [str ]
299+ opts : list [str ]
300+ args : list [str ]
310301 stdout : str
311302 stderr : str
312303 status : int
313- path_lines : Dict [ Optional [ Path ], List [str ]]
304+ path_lines : dict [ Path | None , list [str ]]
314305
315- def dump (self , results_f : IO [bytes ]) -> None :
306+ def dump (self , results_f : typing . IO [bytes ]) -> None :
316307 """Cache results in a format that can be parsed by load()."""
317308 prepared = vars (self ).copy ()
318309 prepared ["path_lines" ] = {
@@ -321,7 +312,7 @@ def dump(self, results_f: IO[bytes]) -> None:
321312 results_f .write (json .dumps (prepared ).encode (self ._encoding ))
322313
323314 @classmethod
324- def load (cls , results_f : IO [bytes ]) -> MypyResults :
315+ def load (cls , results_f : typing . IO [bytes ]) -> MypyResults :
325316 """Get results cached by dump()."""
326317 prepared = json .loads (results_f .read ().decode (cls ._encoding ))
327318 prepared ["path_lines" ] = {
@@ -333,9 +324,9 @@ def load(cls, results_f: IO[bytes]) -> MypyResults:
333324 @classmethod
334325 def from_mypy (
335326 cls ,
336- paths : List [Path ],
327+ paths : list [Path ],
337328 * ,
338- opts : Optional [ List [ str ]] = None ,
329+ opts : list [ str ] | None = None ,
339330 ) -> MypyResults :
340331 """Generate results from mypy."""
341332
@@ -345,7 +336,7 @@ def from_mypy(
345336
346337 stdout , stderr , status = mypy .api .run (opts + args )
347338
348- path_lines : Dict [ Optional [ Path ], List [str ]] = {
339+ path_lines : dict [ Path | None , list [str ]] = {
349340 path .resolve (): [] for path in paths
350341 }
351342 path_lines [None ] = []
0 commit comments