From b447ff994be76db81910eb600e21f7d92c766f5a Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 16 Jul 2026 13:06:30 +0200 Subject: [PATCH 1/6] Refactor `VERSIONS` handling `parse_stdlib_versions_file` now returns a class with methods `supported_versions_for_module` and `is_supported`, obsoleting stand-alone function `supported_versions_for_module`. --- lib/ts_utils/utils.py | 30 +++++++++++++++++++----------- tests/mypy_test.py | 5 +---- tests/ty_test.py | 6 ++---- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/lib/ts_utils/utils.py b/lib/ts_utils/utils.py index 6c8cd022aa70..d72f2abefd3c 100644 --- a/lib/ts_utils/utils.py +++ b/lib/ts_utils/utils.py @@ -149,14 +149,30 @@ def get_mypy_req() -> str: # ==================================================================== VersionTuple: TypeAlias = tuple[int, int] -SupportedVersionsDict: TypeAlias = dict[str, tuple[VersionTuple, VersionTuple]] VERSIONS_PATH = STDLIB_PATH / "VERSIONS" VERSION_LINE_RE = re.compile(r"^([a-zA-Z_][a-zA-Z0-9_.]*): ([23]\.\d{1,2})-([23]\.\d{1,2})?$") VERSION_RE = re.compile(r"^([23])\.(\d+)$") -def parse_stdlib_versions_file() -> SupportedVersionsDict: +class SupportedVersions: + def __init__(self, module_versions: dict[str, tuple[VersionTuple, VersionTuple]]) -> None: + self.module_versions = module_versions + + def supported_versions_for_module(self, module_name: str) -> tuple[VersionTuple, VersionTuple]: + while "." in module_name: + if module_name in self.module_versions: + return self.module_versions[module_name] + module_name = ".".join(module_name.split(".")[:-1]) + return self.module_versions[module_name] + + def is_supported(self, module_name: str, version: str) -> bool: + version_tuple = tuple(map(int, version.split("."))) + minimum, maximum = self.supported_versions_for_module(module_name) + return minimum <= version_tuple <= maximum + + +def parse_stdlib_versions_file() -> SupportedVersions: result: dict[str, tuple[VersionTuple, VersionTuple]] = {} with VERSIONS_PATH.open(encoding="UTF-8") as f: for line in f: @@ -170,15 +186,7 @@ def parse_stdlib_versions_file() -> SupportedVersionsDict: min_version = _parse_version(m.group(2)) max_version = _parse_version(m.group(3)) if m.group(3) else (99, 99) result[mod] = min_version, max_version - return result - - -def supported_versions_for_module(module_versions: SupportedVersionsDict, module_name: str) -> tuple[VersionTuple, VersionTuple]: - while "." in module_name: - if module_name in module_versions: - return module_versions[module_name] - module_name = ".".join(module_name.split(".")[:-1]) - return module_versions[module_name] + return SupportedVersions(result) def _parse_version(v_str: str) -> tuple[int, int]: diff --git a/tests/mypy_test.py b/tests/mypy_test.py index 1fd8a87f2618..e88171f4bfe4 100755 --- a/tests/mypy_test.py +++ b/tests/mypy_test.py @@ -33,7 +33,6 @@ print_error, print_success_msg, spec_matches_path, - supported_versions_for_module, venv_python, ) @@ -311,15 +310,13 @@ def test_stdlib(args: TestConfig) -> TestResult: def remove_modules_not_in_python_version(paths: list[Path], py_version: VersionString) -> list[Path]: - py_version_tuple = tuple(map(int, py_version.split("."))) module_versions = parse_stdlib_versions_file() new_paths: list[Path] = [] for path in paths: if path.parts[0] != "stdlib" or path.suffix != ".pyi": continue module_name = stdlib_module_name_from_path(path) - min_version, max_version = supported_versions_for_module(module_versions, module_name) - if min_version <= py_version_tuple <= max_version: + if module_versions.is_supported(module_name, py_version): new_paths.append(path) return new_paths diff --git a/tests/ty_test.py b/tests/ty_test.py index 909a1f4d852b..9aa087413a32 100755 --- a/tests/ty_test.py +++ b/tests/ty_test.py @@ -9,7 +9,7 @@ from pathlib import Path from ts_utils.paths import STDLIB_PATH, STUBS_PATH, TS_BASE_PATH -from ts_utils.utils import parse_stdlib_versions_file, supported_versions_for_module +from ts_utils.utils import parse_stdlib_versions_file SUPPORTED_VERSIONS = ("3.10", "3.11", "3.12", "3.13", "3.14", "3.15") SUPPORTED_PLATFORMS = ("linux", "darwin", "win32") @@ -19,7 +19,6 @@ def stdlib_files(version: str) -> list[Path]: """Return the stdlib stubs available in the requested Python version.""" - version_tuple = tuple(map(int, version.split("."))) module_versions = parse_stdlib_versions_file() files: list[Path] = [] @@ -33,8 +32,7 @@ def stdlib_files(version: str) -> list[Path]: parts = list(relative.parts[:-1]) if relative.name != "__init__.pyi": parts.append(relative.stem) - minimum, maximum = supported_versions_for_module(module_versions, ".".join(parts)) - if minimum <= version_tuple <= maximum: + if module_versions.is_supported(".".join(parts), version): files.append(path) return files From 7a37198a93ac56b7ec855490219e9a17aab56e98 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 16 Jul 2026 13:09:40 +0200 Subject: [PATCH 2/6] Fix typeshed structure script --- tests/check_typeshed_structure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/check_typeshed_structure.py b/tests/check_typeshed_structure.py index 8c3892ff04a6..8748c80aea5a 100755 --- a/tests/check_typeshed_structure.py +++ b/tests/check_typeshed_structure.py @@ -130,7 +130,7 @@ def check_no_symlinks() -> None: def check_versions_file() -> None: """Check that the stdlib/VERSIONS file has the correct format.""" - version_map = parse_stdlib_versions_file() + version_map = parse_stdlib_versions_file().module_versions versions = list(version_map.keys()) sorted_versions = sorted(versions) From f6d4183ca6071408398c7849dd7ff120a7d7f386 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 16 Jul 2026 13:01:14 +0200 Subject: [PATCH 3/6] Unify stubs discovery * Add a `StubFile` class with sub-classes `StdlibStubFile` and `ThirdPartyStubFile` to describe stubs files. * Add a `stdlib_stubs` function to collect the stdlib stub files for a specific Python version. * Add a `third_party_stubs` function to collect all third-party stub files or the stub files of a specific distribution. * Add `path_stubs` to collect all stub files in a certain path. * `parse_stdlib_versions_file` now returns a class with methods `supported_versions_for_module` and `is_supported`, obsoleting stand-alone function `supported_versions_for_module`. * Use the new function in `mypy_test.py`, `ty_test.py`, and `stubsabot.py`. --- lib/ts_utils/stubs.py | 86 +++++++++++++++++++++++++++++++++++++++++++ scripts/stubsabot.py | 5 ++- tests/mypy_test.py | 80 ++++++++++++---------------------------- tests/ty_test.py | 39 +++++--------------- 4 files changed, 122 insertions(+), 88 deletions(-) create mode 100644 lib/ts_utils/stubs.py diff --git a/lib/ts_utils/stubs.py b/lib/ts_utils/stubs.py new file mode 100644 index 000000000000..c206dbb7579f --- /dev/null +++ b/lib/ts_utils/stubs.py @@ -0,0 +1,86 @@ +from functools import cached_property +from pathlib import Path + +from ts_utils.paths import STDLIB_PATH, STUBS_PATH, TESTS_DIR, distribution_path +from ts_utils.utils import parse_stdlib_versions_file + + +class StubFile: + """A stdlib stub file.""" + + def __init__(self, path: Path) -> None: + self.path = path + + def __fspath__(self) -> str: + return self.path.__fspath__() + + def __str__(self) -> str: + return str(self.path) + + @cached_property + def module_name(self) -> str: + return ".".join(self.module_parts) + + @property + def module_parts(self) -> tuple[str, ...]: + raise NotImplementedError + + +class StdlibStubFile(StubFile): + @cached_property + def module_parts(self) -> tuple[str, ...]: + relative = self.path.relative_to(STDLIB_PATH) + parts = list(relative.parts[:-1]) + if relative.name != "__init__.pyi": + parts.append(relative.stem) + return tuple(parts) + + +class ThirdPartyStubFile(StubFile): + @cached_property + def upstream_distribution(self) -> str: + return self.path.relative_to(STUBS_PATH).parts[0] + + @cached_property + def module_parts(self) -> tuple[str, ...]: + relative = self.path.relative_to(STUBS_PATH) + parts = list(relative.parts[1:-1]) + print(parts) + if relative.name != "__init__.pyi": + parts.append(relative.stem) + return tuple(parts) + + +def stdlib_stubs(version: str) -> list[StdlibStubFile]: + """Return the stdlib stubs available in the requested Python version.""" + module_versions = parse_stdlib_versions_file() + stubs: list[StdlibStubFile] = [] + + for path in sorted(STDLIB_PATH.rglob("*.pyi")): + if TESTS_DIR in path.parts: + continue + stub = StdlibStubFile(path) + if module_versions.is_supported(stub.module_name, version): + stubs.append(stub) + + return stubs + + +def third_party_stubs(distribution: str | None = None) -> list[ThirdPartyStubFile]: + stubs: list[ThirdPartyStubFile] = [] + + stub_path = distribution_path(distribution) if distribution else STUBS_PATH + + for path in sorted(stub_path.rglob("*.pyi")): + if TESTS_DIR in path.parts: + continue + stubs.append(ThirdPartyStubFile(path)) + + return stubs + + +def path_stubs(path: Path) -> list[Path]: + """Return all stubs in a certain path.""" + if path.is_file(): + return [path] if path.suffix == ".pyi" and TESTS_DIR not in path.parts else [] + return sorted(p for p in path.rglob("*.pyi") if TESTS_DIR not in p.parts) diff --git a/scripts/stubsabot.py b/scripts/stubsabot.py index d7fff130d826..293a6420d09d 100755 --- a/scripts/stubsabot.py +++ b/scripts/stubsabot.py @@ -38,6 +38,7 @@ from ts_utils.metadata import ObsoleteMetadata, StubMetadata, read_metadata, update_metadata from ts_utils.paths import PYRIGHT_CONFIG, STUBS_PATH, distribution_path +from ts_utils.stubs import third_party_stubs TYPESHED_OWNER = "python" TYPESHED_API_URL = f"https://api.github.com/repos/{TYPESHED_OWNER}/typeshed" @@ -534,7 +535,7 @@ async def analyze_github_diff( # https://docs.github.com/en/rest/commits/commits#compare-two-commits py_files: list[FileInfo] = [file for file in json_resp["files"] if Path(file["filename"]).suffix == ".py"] stub_path = distribution_path(distribution) - files_in_typeshed = set(stub_path.rglob("*.pyi")) + files_in_typeshed = {stub.path for stub in third_party_stubs(distribution)} py_files_stubbed_in_typeshed = [file for file in py_files if (stub_path / f"{file['filename']}i") in files_in_typeshed] return DiffAnalysis(py_files=py_files, py_files_stubbed_in_typeshed=py_files_stubbed_in_typeshed) @@ -570,7 +571,7 @@ async def analyze_gitlab_diff( py_files.append(FileInfo(filename=filename, status=status, additions=additions, deletions=deletions)) stub_path = distribution_path(distribution) - files_in_typeshed = set(stub_path.rglob("*.pyi")) + files_in_typeshed = {stub.path for stub in third_party_stubs(distribution)} py_files_stubbed_in_typeshed = [file for file in py_files if (stub_path / f"{file['filename']}i") in files_in_typeshed] return DiffAnalysis(py_files=py_files, py_files_stubbed_in_typeshed=py_files_stubbed_in_typeshed) diff --git a/tests/mypy_test.py b/tests/mypy_test.py index e88171f4bfe4..5fc27e108787 100755 --- a/tests/mypy_test.py +++ b/tests/mypy_test.py @@ -22,14 +22,14 @@ from ts_utils.metadata import PackageDependencies, get_recursive_requirements, read_metadata from ts_utils.mypy import MypyDistConf, mypy_configuration_from_distribution, temporary_mypy_config_file -from ts_utils.paths import STDLIB_PATH, STUBS_PATH, TESTS_DIR, TS_BASE_PATH, distribution_path +from ts_utils.paths import STDLIB_PATH, STUBS_PATH, TS_BASE_PATH, distribution_path from ts_utils.py315 import PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES +from ts_utils.stubs import StubFile, stdlib_stubs, third_party_stubs from ts_utils.utils import ( PYTHON_VERSION, colored, get_gitignore_spec, get_mypy_req, - parse_stdlib_versions_file, print_error, print_success_msg, spec_matches_path, @@ -125,39 +125,28 @@ def log(args: TestConfig, *varargs: object) -> None: print(colored(" ".join(map(str, varargs)), "blue")) -def match(path: Path, args: TestConfig) -> bool: +def match(stub: StubFile, args: TestConfig) -> bool: for excluded_path in args.exclude: - if path == excluded_path: - log(args, path, "explicitly excluded") + if stub.path == excluded_path: + log(args, stub, "explicitly excluded") return False - if excluded_path in path.parents: - log(args, path, f'is in an explicitly excluded directory "{excluded_path}"') + if excluded_path in stub.path.parents: + log(args, stub, f'is in an explicitly excluded directory "{excluded_path}"') return False for included_path in args.filter: - if path == included_path: - log(args, path, "was explicitly included") + if stub.path == included_path: + log(args, stub, "was explicitly included") return True - if included_path in path.parents: - log(args, path, f'is in an explicitly included directory "{included_path}"') + if included_path in stub.path.parents: + log(args, stub, f'is in an explicitly included directory "{included_path}"') return True log_msg = ( f'is implicitly excluded: was not in any of the directories or paths specified on the command line: "{args.filter!r}"' ) - log(args, path, log_msg) + log(args, stub.path, log_msg) return False -def add_files(files: list[Path], module: Path, args: TestConfig) -> None: - """Add all files in package or module represented by 'name' located in 'root'.""" - if module.name.startswith("."): - return - if module.is_file() and module.suffix == ".pyi": - if match(module, args): - files.append(module) - else: - files.extend(sorted(file for file in module.rglob("*.pyi") if match(file, args))) - - class MypyResult(Enum): SUCCESS = 0 FAILURE = 1 @@ -238,15 +227,18 @@ def run_mypy( return MypyResult.from_process_result(result) -def add_third_party_files(distribution: str, files: list[Path], args: TestConfig, seen_dists: set[str]) -> None: +def distribution_files(distribution: str, args: TestConfig, seen_dists: set[str]) -> list[Path]: typeshed_reqs = get_recursive_requirements(distribution).typeshed_pkgs if distribution in seen_dists: - return + return [] seen_dists.add(distribution) seen_dists.update(r.name for r in typeshed_reqs) - root = distribution_path(distribution) - for path in root.iterdir(): - add_files(files, path, args) + + stubs = [] + for stub in third_party_stubs(distribution): + if match(stub, args): + stubs.append(stub.path) + return stubs class TestResult(NamedTuple): @@ -262,9 +254,8 @@ def test_third_party_distribution( Return a tuple, where the first element indicates mypy's return code and the second element is the number of checked files. """ - files: list[Path] = [] seen_dists: set[str] = set() - add_third_party_files(distribution, files, args, seen_dists) + files = distribution_files(distribution, args, seen_dists) configurations = mypy_configuration_from_distribution(distribution) if not files and args.filter: @@ -293,12 +284,10 @@ def test_third_party_distribution( def test_stdlib(args: TestConfig) -> TestResult: files: list[Path] = [] - for file in STDLIB_PATH.iterdir(): - if file.name in ("VERSIONS", TESTS_DIR): - continue - add_files(files, file, args) - files = remove_modules_not_in_python_version(files, args.version) + for stub in stdlib_stubs(args.version): + if match(stub, args): + files.append(stub.path) if not files: return TestResult(MypyResult.SUCCESS, 0) @@ -309,27 +298,6 @@ def test_stdlib(args: TestConfig) -> TestResult: return TestResult(result, len(files)) -def remove_modules_not_in_python_version(paths: list[Path], py_version: VersionString) -> list[Path]: - module_versions = parse_stdlib_versions_file() - new_paths: list[Path] = [] - for path in paths: - if path.parts[0] != "stdlib" or path.suffix != ".pyi": - continue - module_name = stdlib_module_name_from_path(path) - if module_versions.is_supported(module_name, py_version): - new_paths.append(path) - return new_paths - - -def stdlib_module_name_from_path(path: Path) -> str: - assert path.parts[0] == "stdlib" - assert path.suffix == ".pyi" - parts = list(path.parts[1:-1]) - if path.parts[-1] != "__init__.pyi": - parts.append(path.parts[-1].removesuffix(".pyi")) - return ".".join(parts) - - @dataclass class TestSummary: mypy_result: MypyResult = MypyResult.SUCCESS diff --git a/tests/ty_test.py b/tests/ty_test.py index 9aa087413a32..a015534f7cdd 100755 --- a/tests/ty_test.py +++ b/tests/ty_test.py @@ -9,7 +9,7 @@ from pathlib import Path from ts_utils.paths import STDLIB_PATH, STUBS_PATH, TS_BASE_PATH -from ts_utils.utils import parse_stdlib_versions_file +from ts_utils.stubs import path_stubs, stdlib_stubs, third_party_stubs SUPPORTED_VERSIONS = ("3.10", "3.11", "3.12", "3.13", "3.14", "3.15") SUPPORTED_PLATFORMS = ("linux", "darwin", "win32") @@ -19,34 +19,17 @@ def stdlib_files(version: str) -> list[Path]: """Return the stdlib stubs available in the requested Python version.""" - module_versions = parse_stdlib_versions_file() - files: list[Path] = [] + # ty cannot resolve relative imports in the legacy distutils stubs. + return [stub.path for stub in stdlib_stubs(version) if stub.module_parts[0] != "distutils"] - for path in sorted(STDLIB_PATH.rglob("*.pyi")): - if "@tests" in path.parts: - continue - relative = path.relative_to(STDLIB_PATH) - # ty cannot resolve relative imports in the legacy distutils stubs. - if relative.parts[0] == "distutils": - continue - parts = list(relative.parts[:-1]) - if relative.name != "__init__.pyi": - parts.append(relative.stem) - if module_versions.is_supported(".".join(parts), version): - files.append(path) - return files - - -def _path_files(path: Path) -> list[Path]: - if path.is_file(): - return [path] if path.suffix == ".pyi" and "@tests" not in path.parts else [] - return sorted(p for p in path.rglob("*.pyi") if "@tests" not in p.parts) +def third_party_files() -> list[Path]: + return [stub.path for stub in third_party_stubs() if stub.upstream_distribution not in EXCLUDED_STUBS] def _filter_files(files: list[Path], paths: list[Path], root: Path) -> list[Path]: selected_paths = [path if path.is_absolute() else TS_BASE_PATH / path for path in paths] - selected_files = {file for path in selected_paths if path.is_relative_to(root) for file in _path_files(path)} + selected_files = {file for path in selected_paths if path.is_relative_to(root) for file in path_stubs(path)} return [file for file in files if file in selected_files] @@ -58,16 +41,12 @@ def main() -> int: parser.add_argument("--platform", choices=SUPPORTED_PLATFORMS, default="linux") args = parser.parse_args() - third_party_files = sorted( - path - for path in STUBS_PATH.rglob("*.pyi") - if "@tests" not in path.parts and path.relative_to(STUBS_PATH).parts[0] not in EXCLUDED_STUBS - ) stdlib = stdlib_files(args.python_version) + third_party = third_party_files() if args.paths: stdlib = _filter_files(stdlib, args.paths, STDLIB_PATH) - third_party_files = _filter_files(third_party_files, args.paths, STUBS_PATH) - files = [*stdlib, *third_party_files] + third_party = _filter_files(third_party, args.paths, STUBS_PATH) + files = [*stdlib, *third_party] if not files: print("No stubs to check with ty.", flush=True) return 0 From 9fa17b8ebb3c4f2007fba0bb64b04551d1d866b1 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 16 Jul 2026 13:16:25 +0200 Subject: [PATCH 4/6] Fix type errors --- lib/ts_utils/stubs.py | 2 +- tests/mypy_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ts_utils/stubs.py b/lib/ts_utils/stubs.py index c206dbb7579f..c79cc6f617cf 100644 --- a/lib/ts_utils/stubs.py +++ b/lib/ts_utils/stubs.py @@ -21,7 +21,7 @@ def __str__(self) -> str: def module_name(self) -> str: return ".".join(self.module_parts) - @property + @cached_property def module_parts(self) -> tuple[str, ...]: raise NotImplementedError diff --git a/tests/mypy_test.py b/tests/mypy_test.py index 5fc27e108787..0ab05c585e39 100755 --- a/tests/mypy_test.py +++ b/tests/mypy_test.py @@ -234,7 +234,7 @@ def distribution_files(distribution: str, args: TestConfig, seen_dists: set[str] seen_dists.add(distribution) seen_dists.update(r.name for r in typeshed_reqs) - stubs = [] + stubs: list[Path] = [] for stub in third_party_stubs(distribution): if match(stub, args): stubs.append(stub.path) From 6ff100864a3d768b6575d106ee1bebcc372ae1f7 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 16 Jul 2026 13:20:07 +0200 Subject: [PATCH 5/6] Fix and add docstrings --- lib/ts_utils/stubs.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/ts_utils/stubs.py b/lib/ts_utils/stubs.py index c79cc6f617cf..0efc4ed4ffcc 100644 --- a/lib/ts_utils/stubs.py +++ b/lib/ts_utils/stubs.py @@ -1,3 +1,5 @@ +"""Stub file discovery.""" + from functools import cached_property from pathlib import Path @@ -6,7 +8,7 @@ class StubFile: - """A stdlib stub file.""" + """Base class for stub files.""" def __init__(self, path: Path) -> None: self.path = path @@ -27,6 +29,8 @@ def module_parts(self) -> tuple[str, ...]: class StdlibStubFile(StubFile): + """A stdlib stub file.""" + @cached_property def module_parts(self) -> tuple[str, ...]: relative = self.path.relative_to(STDLIB_PATH) @@ -37,6 +41,8 @@ def module_parts(self) -> tuple[str, ...]: class ThirdPartyStubFile(StubFile): + """A third-party stub file.""" + @cached_property def upstream_distribution(self) -> str: return self.path.relative_to(STUBS_PATH).parts[0] @@ -52,7 +58,8 @@ def module_parts(self) -> tuple[str, ...]: def stdlib_stubs(version: str) -> list[StdlibStubFile]: - """Return the stdlib stubs available in the requested Python version.""" + """Return the stdlib stubs available for the requested Python version.""" + module_versions = parse_stdlib_versions_file() stubs: list[StdlibStubFile] = [] @@ -67,6 +74,12 @@ def stdlib_stubs(version: str) -> list[StdlibStubFile]: def third_party_stubs(distribution: str | None = None) -> list[ThirdPartyStubFile]: + """Return third-party stubs. + + If distribution is None, return all third-party stubs. Otherwise, + return only stubs for the given distribution. + """ + stubs: list[ThirdPartyStubFile] = [] stub_path = distribution_path(distribution) if distribution else STUBS_PATH @@ -80,7 +93,7 @@ def third_party_stubs(distribution: str | None = None) -> list[ThirdPartyStubFil def path_stubs(path: Path) -> list[Path]: - """Return all stubs in a certain path.""" + """Return paths to all stub files in a certain path.""" if path.is_file(): return [path] if path.suffix == ".pyi" and TESTS_DIR not in path.parts else [] return sorted(p for p in path.rglob("*.pyi") if TESTS_DIR not in p.parts) From 880c6b767358b1fbe32362f129b1b467e0acf1ff Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Fri, 17 Jul 2026 13:07:56 +0200 Subject: [PATCH 6/6] Use a list comprehensions --- tests/mypy_test.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/tests/mypy_test.py b/tests/mypy_test.py index 0ab05c585e39..dd065f3a07b0 100755 --- a/tests/mypy_test.py +++ b/tests/mypy_test.py @@ -227,18 +227,14 @@ def run_mypy( return MypyResult.from_process_result(result) -def distribution_files(distribution: str, args: TestConfig, seen_dists: set[str]) -> list[Path]: +def distribution_stub_files(distribution: str, args: TestConfig, seen_dists: set[str]) -> list[Path]: typeshed_reqs = get_recursive_requirements(distribution).typeshed_pkgs if distribution in seen_dists: return [] seen_dists.add(distribution) seen_dists.update(r.name for r in typeshed_reqs) - stubs: list[Path] = [] - for stub in third_party_stubs(distribution): - if match(stub, args): - stubs.append(stub.path) - return stubs + return [stub.path for stub in third_party_stubs(distribution) if match(stub, args)] class TestResult(NamedTuple): @@ -255,7 +251,7 @@ def test_third_party_distribution( and the second element is the number of checked files. """ seen_dists: set[str] = set() - files = distribution_files(distribution, args, seen_dists) + files = distribution_stub_files(distribution, args, seen_dists) configurations = mypy_configuration_from_distribution(distribution) if not files and args.filter: @@ -283,11 +279,7 @@ def test_third_party_distribution( def test_stdlib(args: TestConfig) -> TestResult: - files: list[Path] = [] - - for stub in stdlib_stubs(args.version): - if match(stub, args): - files.append(stub.path) + files = [stub.path for stub in stdlib_stubs(args.version) if match(stub, args)] if not files: return TestResult(MypyResult.SUCCESS, 0)