diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py index 4808d0e61f7038..56030f8cf9de54 100644 --- a/Lib/pathlib/_abc.py +++ b/Lib/pathlib/_abc.py @@ -61,11 +61,8 @@ def _compile_pattern(pat, sep, case_sensitive): if re is None: import re, glob - flags = re.NOFLAG if case_sensitive else re.IGNORECASE + flags = 0 if case_sensitive else re.IGNORECASE regex = glob.translate(pat, recursive=True, include_hidden=True, seps=sep) - # The string representation of an empty path is a single dot ('.'). Empty - # paths shouldn't match wildcards, so we consume it with an atomic group. - regex = r'(\.\Z)?+' + regex return re.compile(regex, flags=flags).match @@ -277,6 +274,14 @@ def __str__(self): self._tail) or '.' return self._str + @property + def _pattern_str(self): + """A string representation of the path, suitable for pattern matching. + This differs from __str__() by representing empty paths as the empty + string '', rather than a dot '.' character.""" + path_str = str(self) + return '' if path_str == '.' else path_str + def as_posix(self): """Return the string representation of the path with forward (/) slashes.""" @@ -528,7 +533,7 @@ def match(self, path_pattern, *, case_sensitive=None): else: raise ValueError("empty pattern") match = _compile_pattern(pattern_str, sep, case_sensitive) - return match(str(self)) is not None + return match(self._pattern_str) is not None @@ -882,9 +887,9 @@ def _glob(self, pattern, case_sensitive, follow_symlinks): paths = _select_recursive(paths, dir_only, follow_symlinks) # Filter out paths that don't match pattern. - prefix_len = len(str(self._make_child_relpath('_'))) - 1 + prefix_len = len(self._make_child_relpath('_')._pattern_str) - 1 match = _compile_pattern(str(path_pattern), sep, case_sensitive) - paths = (path for path in paths if match(str(path), prefix_len)) + paths = (path for path in paths if match(path._pattern_str, prefix_len)) return paths dir_only = part_idx < len(pattern_parts)