Skip to content

Commit 8582325

Browse files
committed
Regression tests: Handle no packages gracefully
Before, when running regression tests for a certain version/platform combination that doesn't have any cases, mypy is run with invalid arguments (no files), and the tests fail. Now, a message is printed instead (unless the verbosity is `QUIET`) and the tests succeed.
1 parent c9e422d commit 8582325

2 files changed

Lines changed: 43 additions & 14 deletions

File tree

lib/ts_utils/utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ def print_warning(message: str) -> None:
8383
print(colored(message, "yellow"))
8484

8585

86+
def print_skipped(message: str) -> None:
87+
print(colored(message, "yellow"))
88+
89+
8690
def print_error(error: str, end: str = "\n", fix_path: tuple[str, str] = ("", "")) -> None:
8791
error_split = error.split("\n")
8892
old, new = fix_path

tests/regr_test.py

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
get_all_testcase_directories,
3434
get_mypy_req,
3535
print_error,
36+
print_skipped,
3637
venv_python,
3738
)
3839

@@ -167,7 +168,7 @@ def setup_testcase_dir(package: DistributionTests, tempdir: Path, verbosity: Ver
167168

168169
def run_testcases(
169170
package: DistributionTests, version: str, platform: str, *, tempdir: Path, verbosity: Verbosity
170-
) -> subprocess.CompletedProcess[str]:
171+
) -> subprocess.CompletedProcess[str] | None:
171172
env_vars = dict(os.environ)
172173
new_test_case_dir = tempdir / TEST_CASES_DIR
173174

@@ -177,7 +178,6 @@ def run_testcases(
177178
configurations = mypy_configuration_from_distribution(package.name)
178179

179180
with temporary_mypy_config_file(configurations) as temp_config:
180-
181181
# "--enable-error-code ignore-without-code" is purposefully omitted.
182182
# See https://github.com/python/typeshed/pull/8083
183183
flags = [
@@ -216,18 +216,22 @@ def run_testcases(
216216

217217
flags.extend(["--custom-typeshed-dir", str(custom_typeshed)])
218218

219-
# If the test-case filename ends with -py39,
220-
# only run the test if --python-version was set to 3.9 or higher (for example)
219+
# If the test-case filename ends with e.g. -py314,
220+
# only run the test if --python-version was set to 3.14 or higher (for example)
221+
files: list[str] = []
221222
for path in new_test_case_dir.rglob("*.py"):
222-
if match := re.fullmatch(r".*-py3(\d{1,2})", path.stem):
223+
if match := re.fullmatch(r".*-py3(\d\d)", path.stem):
223224
minor_version_required = int(match[1])
224225
assert f"3.{minor_version_required}" in SUPPORTED_VERSIONS
225226
python_minor_version = int(version.split(".")[1])
226227
if minor_version_required > python_minor_version:
227228
continue
228-
flags.append(str(path))
229+
files.append(str(path))
230+
231+
if len(files) == 0:
232+
return None
229233

230-
mypy_command = [python_exe, "-m", "mypy", *flags]
234+
mypy_command = [python_exe, "-m", "mypy", *flags, *files]
231235
if verbosity is Verbosity.VERBOSE:
232236
description = f"{package.name}/{version}/{platform}"
233237
msg = f"{description}: {mypy_command=}\n"
@@ -243,13 +247,20 @@ def run_testcases(
243247
@dataclass(frozen=True)
244248
class Result:
245249
code: int
250+
251+
def print_description(self, verbosity: Verbosity) -> None:
252+
raise NotImplementedError
253+
254+
255+
@dataclass(frozen=True)
256+
class RunResult(Result):
246257
command_run: str
247258
stderr: str
248259
stdout: str
249260
test_case_dir: Path
250261
tempdir: Path
251262

252-
def print_description(self) -> None:
263+
def print_description(self, _: Verbosity) -> None:
253264
if self.code:
254265
print(f"{self.command_run}:", end=" ")
255266
print_error("FAILURE\n")
@@ -260,6 +271,17 @@ def print_description(self) -> None:
260271
print_error(self.stdout, fix_path=replacements)
261272

262273

274+
@dataclass(frozen=True)
275+
class NoTestsResult(Result):
276+
package: str
277+
version: str
278+
platform: str
279+
280+
def print_description(self, verbosity: Verbosity) -> None:
281+
if verbosity != Verbosity.QUIET:
282+
print_skipped(f"No test cases found for {self.package!r} on Python {self.version} for platform {self.platform!r}.")
283+
284+
263285
def test_testcase_directory(
264286
package: DistributionTests, version: str, platform: str, *, verbosity: Verbosity, tempdir: Path
265287
) -> Result:
@@ -268,12 +290,15 @@ def test_testcase_directory(
268290
if verbosity > Verbosity.QUIET:
269291
_PRINT_QUEUE.put(f"Running {msg}...")
270292

271-
proc_info = run_testcases(package=package, version=version, platform=platform, tempdir=tempdir, verbosity=verbosity)
272-
return Result(
273-
code=proc_info.returncode,
293+
result = run_testcases(package=package, version=version, platform=platform, tempdir=tempdir, verbosity=verbosity)
294+
if result is None:
295+
return NoTestsResult(0, package.name, version, platform)
296+
297+
return RunResult(
298+
code=result.returncode,
274299
command_run=msg,
275-
stderr=proc_info.stderr,
276-
stdout=proc_info.stdout,
300+
stderr=result.stderr,
301+
stdout=result.stdout,
277302
test_case_dir=package.test_cases_path,
278303
tempdir=tempdir,
279304
)
@@ -399,7 +424,7 @@ def main() -> ReturnCode:
399424
print()
400425

401426
for result in results:
402-
result.print_description()
427+
result.print_description(verbosity)
403428

404429
code = max(result.code for result in results)
405430

0 commit comments

Comments
 (0)