bpo-31202: Preserve case of literal parts in Path.glob() on Windows. … · python/cpython@175abcc

@@ -187,6 +187,9 @@ def casefold(self, s):

187187

def casefold_parts(self, parts):

188188

return [p.lower() for p in parts]

189189190+

def compile_pattern(self, pattern):

191+

return re.compile(fnmatch.translate(pattern), re.IGNORECASE).fullmatch

192+190193

def resolve(self, path, strict=False):

191194

s = str(path)

192195

if not s:

@@ -309,6 +312,9 @@ def casefold(self, s):

309312

def casefold_parts(self, parts):

310313

return parts

311314315+

def compile_pattern(self, pattern):

316+

return re.compile(fnmatch.translate(pattern)).fullmatch

317+312318

def resolve(self, path, strict=False):

313319

sep = self.sep

314320

accessor = 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):

448454

pat = pattern_parts[0]

449455

child_parts = pattern_parts[1:]

450456

if pat == '**':

@@ -455,7 +461,7 @@ def _make_selector(pattern_parts):

455461

cls = _WildcardSelector

456462

else:

457463

cls = _PreciseSelector

458-

return cls(pat, child_parts)

464+

return cls(pat, child_parts, flavour)

459465460466

if 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):

469475

self.child_parts = child_parts

470476

if child_parts:

471-

self.successor = _make_selector(child_parts)

477+

self.successor = _make_selector(child_parts, flavour)

472478

self.dironly = True

473479

else:

474480

self.successor = _TerminatingSelector()

@@ -494,9 +500,9 @@ def _select_from(self, parent_path, is_dir, exists, scandir):

494500495501

class _PreciseSelector(_Selector):

496502497-

def __init__(self, name, child_parts):

503+

def __init__(self, name, child_parts, flavour):

498504

self.name = name

499-

_Selector.__init__(self, child_parts)

505+

_Selector.__init__(self, child_parts, flavour)

500506501507

def _select_from(self, parent_path, is_dir, exists, scandir):

502508

try:

@@ -510,13 +516,12 @@ def _select_from(self, parent_path, is_dir, exists, scandir):

510516511517

class _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)

516522517523

def _select_from(self, parent_path, is_dir, exists, scandir):

518524

try:

519-

cf = parent_path._flavour.casefold

520525

entries = list(scandir(parent_path))

521526

for entry in entries:

522527

entry_is_dir = False

@@ -527,8 +532,7 @@ def _select_from(self, parent_path, is_dir, exists, scandir):

527532

raise

528533

if not self.dironly or entry_is_dir:

529534

name = entry.name

530-

casefolded = cf(name)

531-

if self.pat.match(casefolded):

535+

if self.match(name):

532536

path = parent_path._make_child_relpath(name)

533537

for p in self.successor._select_from(path, is_dir, exists, scandir):

534538

yield p

@@ -539,8 +543,8 @@ def _select_from(self, parent_path, is_dir, exists, scandir):

539543540544

class _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)

544548545549

def _iterate_directories(self, parent_path, is_dir, scandir):

546550

yield parent_path

@@ -1101,11 +1105,10 @@ def glob(self, pattern):

11011105

"""

11021106

if not pattern:

11031107

raise ValueError("Unacceptable pattern: {!r}".format(pattern))

1104-

pattern = self._flavour.casefold(pattern)

11051108

drv, root, pattern_parts = self._flavour.parse_parts((pattern,))

11061109

if drv or root:

11071110

raise NotImplementedError("Non-relative patterns are unsupported")

1108-

selector = _make_selector(tuple(pattern_parts))

1111+

selector = _make_selector(tuple(pattern_parts), self._flavour)

11091112

for p in selector.select_from(self):

11101113

yield 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)

11181120

drv, root, pattern_parts = self._flavour.parse_parts((pattern,))

11191121

if drv or root:

11201122

raise NotImplementedError("Non-relative patterns are unsupported")

1121-

selector = _make_selector(("**",) + tuple(pattern_parts))

1123+

selector = _make_selector(("**",) + tuple(pattern_parts), self._flavour)

11221124

for p in selector.select_from(self):

11231125

yield p

11241126