1import os 2import sys 3import unittest 4 5from test import support 6 7from .filter import match_test, set_match_tests 8from .utils import ( 9 StrPath, TestName, TestTuple, TestList, TestFilter, 10 abs_module_name, count, printlist) 11 12 13# If these test directories are encountered recurse into them and treat each 14# "test_*.py" file or each sub-directory as a separate test module. This can 15# increase parallelism. 16# 17# Beware this can't generally be done for any directory with sub-tests as the 18# __init__.py may do things which alter what tests are to be run. 19SPLITTESTDIRS: set[TestName] = { 20 "test_asyncio", 21 "test_concurrent_futures", 22 "test_doctests", 23 "test_future_stmt", 24 "test_gdb", 25 "test_inspect", 26 "test_pydoc", 27 "test_multiprocessing_fork", 28 "test_multiprocessing_forkserver", 29 "test_multiprocessing_spawn", 30} 31 32 33def findtestdir(path: StrPath | None = None) -> StrPath: 34 return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir 35 36 37def findtests(*, testdir: StrPath | None = None, exclude=(), 38 split_test_dirs: set[TestName] = SPLITTESTDIRS, 39 base_mod: str = "") -> TestList: 40 """Return a list of all applicable test modules.""" 41 testdir = findtestdir(testdir) 42 tests = [] 43 for name in os.listdir(testdir): 44 mod, ext = os.path.splitext(name) 45 if (not mod.startswith("test_")) or (mod in exclude): 46 continue 47 if base_mod: 48 fullname = f"{base_mod}.{mod}" 49 else: 50 fullname = mod 51 if fullname in split_test_dirs: 52 subdir = os.path.join(testdir, mod) 53 if not base_mod: 54 fullname = f"test.{mod}" 55 tests.extend(findtests(testdir=subdir, exclude=exclude, 56 split_test_dirs=split_test_dirs, 57 base_mod=fullname)) 58 elif ext in (".py", ""): 59 tests.append(fullname) 60 return sorted(tests) 61 62 63def split_test_packages(tests, *, testdir: StrPath | None = None, exclude=(), 64 split_test_dirs=SPLITTESTDIRS): 65 testdir = findtestdir(testdir) 66 splitted = [] 67 for name in tests: 68 if name in split_test_dirs: 69 subdir = os.path.join(testdir, name) 70 splitted.extend(findtests(testdir=subdir, exclude=exclude, 71 split_test_dirs=split_test_dirs, 72 base_mod=name)) 73 else: 74 splitted.append(name) 75 return splitted 76 77 78def _list_cases(suite): 79 for test in suite: 80 if isinstance(test, unittest.loader._FailedTest): 81 continue 82 if isinstance(test, unittest.TestSuite): 83 _list_cases(test) 84 elif isinstance(test, unittest.TestCase): 85 if match_test(test): 86 print(test.id()) 87 88def list_cases(tests: TestTuple, *, 89 match_tests: TestFilter | None = None, 90 test_dir: StrPath | None = None): 91 support.verbose = False 92 set_match_tests(match_tests) 93 94 skipped = [] 95 for test_name in tests: 96 module_name = abs_module_name(test_name, test_dir) 97 try: 98 suite = unittest.defaultTestLoader.loadTestsFromName(module_name) 99 _list_cases(suite) 100 except unittest.SkipTest: 101 skipped.append(test_name) 102 103 if skipped: 104 sys.stdout.flush() 105 stderr = sys.stderr 106 print(file=stderr) 107 print(count(len(skipped), "test"), "skipped:", file=stderr) 108 printlist(skipped, file=stderr) 109