Represents a collection of pattern objects to match paths against. *fallback* is a boolean value that *match()* returns if no matching patterns are found.
| 69 | |
| 70 | |
| 71 | class PatternMatcher: |
| 72 | """Represents a collection of pattern objects to match paths against. |
| 73 | |
| 74 | *fallback* is a boolean value that *match()* returns if no matching patterns are found. |
| 75 | |
| 76 | """ |
| 77 | |
| 78 | def __init__(self, fallback=None): |
| 79 | self._items = [] |
| 80 | |
| 81 | # Value to return from match function when none of the patterns match. |
| 82 | self.fallback = fallback |
| 83 | |
| 84 | # optimizations |
| 85 | self._path_full_patterns = {} # full path -> return value |
| 86 | |
| 87 | # indicates whether the last match() call ended on a pattern for which |
| 88 | # we should recurse into any matching folder. Will be set to True or |
| 89 | # False when calling match(). |
| 90 | self.recurse_dir = None |
| 91 | |
| 92 | # whether to recurse into directories when no match is found |
| 93 | # TODO: allow modification as a config option? |
| 94 | self.recurse_dir_default = True |
| 95 | |
| 96 | self.include_patterns = [] |
| 97 | |
| 98 | # TODO: move this info to parse_inclexcl_command and store in PatternBase subclass? |
| 99 | self.is_include_cmd = {IECommand.Exclude: False, IECommand.ExcludeNoRecurse: False, IECommand.Include: True} |
| 100 | |
| 101 | def empty(self): |
| 102 | return not len(self._items) and not len(self._path_full_patterns) |
| 103 | |
| 104 | def _add(self, pattern, cmd): |
| 105 | """*cmd* is an IECommand value.""" |
| 106 | if isinstance(pattern, PathFullPattern): |
| 107 | key = pattern.pattern # full, normalized path |
| 108 | self._path_full_patterns[key] = cmd |
| 109 | else: |
| 110 | self._items.append((pattern, cmd)) |
| 111 | |
| 112 | def add(self, patterns, cmd): |
| 113 | """Add list of patterns to internal list. *cmd* indicates whether the |
| 114 | pattern is an include/exclude pattern, and whether recursion should be |
| 115 | done on excluded folders. |
| 116 | """ |
| 117 | for pattern in patterns: |
| 118 | self._add(pattern, cmd) |
| 119 | |
| 120 | def add_includepaths(self, include_paths): |
| 121 | """Used to add inclusion-paths from args.paths (from the command line).""" |
| 122 | include_patterns = [parse_pattern(p, PathPrefixPattern) for p in include_paths] |
| 123 | self.add(include_patterns, IECommand.Include) |
| 124 | self.fallback = not include_patterns |
| 125 | self.include_patterns = include_patterns |
| 126 | |
| 127 | def get_unmatched_include_patterns(self): |
| 128 | """Note that this only returns patterns added via *add_includepaths*, and it |
no outgoing calls