1import itertools 2import operator 3import re 4 5 6# By default, don't filter tests 7_test_matchers = () 8_test_patterns = () 9 10 11def match_test(test): 12 # Function used by support.run_unittest() and regrtest --list-cases 13 result = False 14 for matcher, result in reversed(_test_matchers): 15 if matcher(test.id()): 16 return result 17 return not result 18 19 20def _is_full_match_test(pattern): 21 # If a pattern contains at least one dot, it's considered 22 # as a full test identifier. 23 # Example: 'test.test_os.FileTests.test_access'. 24 # 25 # ignore patterns which contain fnmatch patterns: '*', '?', '[...]' 26 # or '[!...]'. For example, ignore 'test_access*'. 27 return ('.' in pattern) and (not re.search(r'[?*\[\]]', pattern)) 28 29 30def get_match_tests(): 31 global _test_patterns 32 return _test_patterns 33 34 35def set_match_tests(patterns): 36 global _test_matchers, _test_patterns 37 38 if not patterns: 39 _test_matchers = () 40 _test_patterns = () 41 else: 42 itemgetter = operator.itemgetter 43 patterns = tuple(patterns) 44 if patterns != _test_patterns: 45 _test_matchers = [ 46 (_compile_match_function(map(itemgetter(0), it)), result) 47 for result, it in itertools.groupby(patterns, itemgetter(1)) 48 ] 49 _test_patterns = patterns 50 51 52def _compile_match_function(patterns): 53 patterns = list(patterns) 54 55 if all(map(_is_full_match_test, patterns)): 56 # Simple case: all patterns are full test identifier. 57 # The test.bisect_cmd utility only uses such full test identifiers. 58 return set(patterns).__contains__ 59 else: 60 import fnmatch 61 regex = '|'.join(map(fnmatch.translate, patterns)) 62 # The search *is* case sensitive on purpose: 63 # don't use flags=re.IGNORECASE 64 regex_match = re.compile(regex).match 65 66 def match_test_regex(test_id, regex_match=regex_match): 67 if regex_match(test_id): 68 # The regex matches the whole identifier, for example 69 # 'test.test_os.FileTests.test_access'. 70 return True 71 else: 72 # Try to match parts of the test identifier. 73 # For example, split 'test.test_os.FileTests.test_access' 74 # into: 'test', 'test_os', 'FileTests' and 'test_access'. 75 return any(map(regex_match, test_id.split("."))) 76 77 return match_test_regex 78