2222
2323from ts_utils .metadata import PackageDependencies , get_recursive_requirements , read_metadata
2424from ts_utils .mypy import MypyDistConf , mypy_configuration_from_distribution , temporary_mypy_config_file
25- from ts_utils .paths import STDLIB_PATH , STUBS_PATH , TESTS_DIR , TS_BASE_PATH , distribution_path
25+ from ts_utils .paths import STDLIB_PATH , STUBS_PATH , TS_BASE_PATH , distribution_path
2626from ts_utils .py315 import PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES
27+ from ts_utils .stubs import StubFile , stdlib_stubs , third_party_stubs
2728from ts_utils .utils import (
2829 PYTHON_VERSION ,
2930 colored ,
3031 get_gitignore_spec ,
3132 get_mypy_req ,
32- parse_stdlib_versions_file ,
3333 print_error ,
3434 print_success_msg ,
3535 spec_matches_path ,
@@ -125,39 +125,28 @@ def log(args: TestConfig, *varargs: object) -> None:
125125 print (colored (" " .join (map (str , varargs )), "blue" ))
126126
127127
128- def match (path : Path , args : TestConfig ) -> bool :
128+ def match (stub : StubFile , args : TestConfig ) -> bool :
129129 for excluded_path in args .exclude :
130- if path == excluded_path :
131- log (args , path , "explicitly excluded" )
130+ if stub . path == excluded_path :
131+ log (args , stub , "explicitly excluded" )
132132 return False
133- if excluded_path in path .parents :
134- log (args , path , f'is in an explicitly excluded directory "{ excluded_path } "' )
133+ if excluded_path in stub . path .parents :
134+ log (args , stub , f'is in an explicitly excluded directory "{ excluded_path } "' )
135135 return False
136136 for included_path in args .filter :
137- if path == included_path :
138- log (args , path , "was explicitly included" )
137+ if stub . path == included_path :
138+ log (args , stub , "was explicitly included" )
139139 return True
140- if included_path in path .parents :
141- log (args , path , f'is in an explicitly included directory "{ included_path } "' )
140+ if included_path in stub . path .parents :
141+ log (args , stub , f'is in an explicitly included directory "{ included_path } "' )
142142 return True
143143 log_msg = (
144144 f'is implicitly excluded: was not in any of the directories or paths specified on the command line: "{ args .filter !r} "'
145145 )
146- log (args , path , log_msg )
146+ log (args , stub , log_msg )
147147 return False
148148
149149
150- def add_files (files : list [Path ], module : Path , args : TestConfig ) -> None :
151- """Add all files in package or module represented by 'name' located in 'root'."""
152- if module .name .startswith ("." ):
153- return
154- if module .is_file () and module .suffix == ".pyi" :
155- if match (module , args ):
156- files .append (module )
157- else :
158- files .extend (sorted (file for file in module .rglob ("*.pyi" ) if match (file , args )))
159-
160-
161150class MypyResult (Enum ):
162151 SUCCESS = 0
163152 FAILURE = 1
@@ -238,15 +227,14 @@ def run_mypy(
238227 return MypyResult .from_process_result (result )
239228
240229
241- def add_third_party_files (distribution : str , files : list [ Path ], args : TestConfig , seen_dists : set [str ]) -> None :
230+ def distribution_stub_files (distribution : str , args : TestConfig , seen_dists : set [str ]) -> list [ Path ] :
242231 typeshed_reqs = get_recursive_requirements (distribution ).typeshed_pkgs
243232 if distribution in seen_dists :
244- return
233+ return []
245234 seen_dists .add (distribution )
246235 seen_dists .update (r .name for r in typeshed_reqs )
247- root = distribution_path (distribution )
248- for path in root .iterdir ():
249- add_files (files , path , args )
236+
237+ return [stub .path for stub in third_party_stubs (distribution ) if match (stub , args )]
250238
251239
252240class TestResult (NamedTuple ):
@@ -262,9 +250,8 @@ def test_third_party_distribution(
262250 Return a tuple, where the first element indicates mypy's return code
263251 and the second element is the number of checked files.
264252 """
265- files : list [Path ] = []
266253 seen_dists : set [str ] = set ()
267- add_third_party_files (distribution , files , args , seen_dists )
254+ files = distribution_stub_files (distribution , args , seen_dists )
268255 configurations = mypy_configuration_from_distribution (distribution )
269256
270257 if not files and args .filter :
@@ -292,13 +279,7 @@ def test_third_party_distribution(
292279
293280
294281def test_stdlib (args : TestConfig ) -> TestResult :
295- files : list [Path ] = []
296- for file in STDLIB_PATH .iterdir ():
297- if file .name in ("VERSIONS" , TESTS_DIR ):
298- continue
299- add_files (files , file , args )
300-
301- files = remove_modules_not_in_python_version (files , args .version )
282+ files = [stub .path for stub in stdlib_stubs (args .version ) if match (stub , args )]
302283
303284 if not files :
304285 return TestResult (MypyResult .SUCCESS , 0 )
@@ -309,27 +290,6 @@ def test_stdlib(args: TestConfig) -> TestResult:
309290 return TestResult (result , len (files ))
310291
311292
312- def remove_modules_not_in_python_version (paths : list [Path ], py_version : VersionString ) -> list [Path ]:
313- module_versions = parse_stdlib_versions_file ()
314- new_paths : list [Path ] = []
315- for path in paths :
316- if path .parts [0 ] != "stdlib" or path .suffix != ".pyi" :
317- continue
318- module_name = stdlib_module_name_from_path (path )
319- if module_versions .is_supported (module_name , py_version ):
320- new_paths .append (path )
321- return new_paths
322-
323-
324- def stdlib_module_name_from_path (path : Path ) -> str :
325- assert path .parts [0 ] == "stdlib"
326- assert path .suffix == ".pyi"
327- parts = list (path .parts [1 :- 1 ])
328- if path .parts [- 1 ] != "__init__.pyi" :
329- parts .append (path .parts [- 1 ].removesuffix (".pyi" ))
330- return "." .join (parts )
331-
332-
333293@dataclass
334294class TestSummary :
335295 mypy_result : MypyResult = MypyResult .SUCCESS
0 commit comments