bpo-31202: Preserve case of literal parts in Path.glob() on Windows. … · python/cpython@175abcc
@@ -187,6 +187,9 @@ def casefold(self, s):
187187def casefold_parts(self, parts):
188188return [p.lower() for p in parts]
189189190+def compile_pattern(self, pattern):
191+return re.compile(fnmatch.translate(pattern), re.IGNORECASE).fullmatch
192+190193def resolve(self, path, strict=False):
191194s = str(path)
192195if not s:
@@ -309,6 +312,9 @@ def casefold(self, s):
309312def casefold_parts(self, parts):
310313return parts
311314315+def compile_pattern(self, pattern):
316+return re.compile(fnmatch.translate(pattern)).fullmatch
317+312318def resolve(self, path, strict=False):
313319sep = self.sep
314320accessor = path._accessor
@@ -444,7 +450,7 @@ def readlink(self, path):
444450# Globbing helpers
445451#
446452447-def _make_selector(pattern_parts):
453+def _make_selector(pattern_parts, flavour):
448454pat = pattern_parts[0]
449455child_parts = pattern_parts[1:]
450456if pat == '**':
@@ -455,7 +461,7 @@ def _make_selector(pattern_parts):
455461cls = _WildcardSelector
456462else:
457463cls = _PreciseSelector
458-return cls(pat, child_parts)
464+return cls(pat, child_parts, flavour)
459465460466if hasattr(functools, "lru_cache"):
461467_make_selector = functools.lru_cache()(_make_selector)
@@ -465,10 +471,10 @@ class _Selector:
465471"""A selector matches a specific glob pattern part against the children
466472 of a given path."""
467473468-def __init__(self, child_parts):
474+def __init__(self, child_parts, flavour):
469475self.child_parts = child_parts
470476if child_parts:
471-self.successor = _make_selector(child_parts)
477+self.successor = _make_selector(child_parts, flavour)
472478self.dironly = True
473479else:
474480self.successor = _TerminatingSelector()
@@ -494,9 +500,9 @@ def _select_from(self, parent_path, is_dir, exists, scandir):
494500495501class _PreciseSelector(_Selector):
496502497-def __init__(self, name, child_parts):
503+def __init__(self, name, child_parts, flavour):
498504self.name = name
499-_Selector.__init__(self, child_parts)
505+_Selector.__init__(self, child_parts, flavour)
500506501507def _select_from(self, parent_path, is_dir, exists, scandir):
502508try:
@@ -510,13 +516,12 @@ def _select_from(self, parent_path, is_dir, exists, scandir):
510516511517class _WildcardSelector(_Selector):
512518513-def __init__(self, pat, child_parts):
514-self.pat = re.compile(fnmatch.translate(pat))
515-_Selector.__init__(self, child_parts)
519+def __init__(self, pat, child_parts, flavour):
520+self.match = flavour.compile_pattern(pat)
521+_Selector.__init__(self, child_parts, flavour)
516522517523def _select_from(self, parent_path, is_dir, exists, scandir):
518524try:
519-cf = parent_path._flavour.casefold
520525entries = list(scandir(parent_path))
521526for entry in entries:
522527entry_is_dir = False
@@ -527,8 +532,7 @@ def _select_from(self, parent_path, is_dir, exists, scandir):
527532raise
528533if not self.dironly or entry_is_dir:
529534name = entry.name
530-casefolded = cf(name)
531-if self.pat.match(casefolded):
535+if self.match(name):
532536path = parent_path._make_child_relpath(name)
533537for p in self.successor._select_from(path, is_dir, exists, scandir):
534538yield p
@@ -539,8 +543,8 @@ def _select_from(self, parent_path, is_dir, exists, scandir):
539543540544class _RecursiveWildcardSelector(_Selector):
541545542-def __init__(self, pat, child_parts):
543-_Selector.__init__(self, child_parts)
546+def __init__(self, pat, child_parts, flavour):
547+_Selector.__init__(self, child_parts, flavour)
544548545549def _iterate_directories(self, parent_path, is_dir, scandir):
546550yield parent_path
@@ -1101,11 +1105,10 @@ def glob(self, pattern):
11011105 """
11021106if not pattern:
11031107raise ValueError("Unacceptable pattern: {!r}".format(pattern))
1104-pattern = self._flavour.casefold(pattern)
11051108drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
11061109if drv or root:
11071110raise NotImplementedError("Non-relative patterns are unsupported")
1108-selector = _make_selector(tuple(pattern_parts))
1111+selector = _make_selector(tuple(pattern_parts), self._flavour)
11091112for p in selector.select_from(self):
11101113yield p
11111114@@ -1114,11 +1117,10 @@ def rglob(self, pattern):
11141117 directories) matching the given relative pattern, anywhere in
11151118 this subtree.
11161119 """
1117-pattern = self._flavour.casefold(pattern)
11181120drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
11191121if drv or root:
11201122raise NotImplementedError("Non-relative patterns are unsupported")
1121-selector = _make_selector(("**",) + tuple(pattern_parts))
1123+selector = _make_selector(("**",) + tuple(pattern_parts), self._flavour)
11221124for p in selector.select_from(self):
11231125yield p
11241126