22
33from __future__ import annotations
44
5+ import re
56import subprocess
67import sys
78from pathlib import Path
1112REPO_ROOT = Path (__file__ ).resolve ().parent .parent
1213MYPY_TYPES_DIR = REPO_ROOT / "tests" / "mypy_types"
1314
15+ _INVALID_FIXTURE = "message_dict_invalid.py"
16+ _INVALID_ERROR_LINES = (6 , 9 )
17+
1418
1519def _run_mypy_on (path : Path ) -> subprocess .CompletedProcess [str ]:
1620 return subprocess .run (
@@ -30,10 +34,15 @@ def _run_mypy_on(path: Path) -> subprocess.CompletedProcess[str]:
3034 )
3135
3236
37+ def _typeddict_item_error_lines (output : str , fixture_name : str ) -> set [int ]:
38+ pattern = rf"{ re .escape (fixture_name )} :(\d+): error:.*\[typeddict-item\]"
39+ return {int (match .group (1 )) for match in re .finditer (pattern , output )}
40+
41+
3342@pytest .mark .parametrize (
3443 ("fixture_name" , "should_pass" ),
3544 [
36- ("message_dict_invalid.py" , False ),
45+ (_INVALID_FIXTURE , False ),
3746 ("message_dict_valid.py" , True ),
3847 ],
3948)
@@ -44,4 +53,8 @@ def test_message_dict_mypy_fixtures(fixture_name: str, should_pass: bool) -> Non
4453 assert result .returncode == 0 , output
4554 else :
4655 assert result .returncode != 0
47- assert "typeddict-item" in output
56+ error_lines = _typeddict_item_error_lines (output , fixture_name )
57+ assert error_lines >= set (_INVALID_ERROR_LINES ), (
58+ f"expected typeddict-item on lines { _INVALID_ERROR_LINES } , "
59+ f"got { sorted (error_lines )} : { output } "
60+ )
0 commit comments