From bbd6d17ef85e5de885cdfab0ae567184ba1550ff Mon Sep 17 00:00:00 2001 From: Barney Gale Date: Sun, 9 Mar 2025 16:36:59 +0000 Subject: GH-130614: pathlib ABCs: support alternate separator in `full_match()` (#130991) In `pathlib.types._JoinablePath.full_match()`, treat alternate path separators in the path and pattern as if they were primary separators. e.g. if the parser is `ntpath`, then `P(r'foo/bar\baz').full_match(r'*\*/*')` is true. --- Lib/glob.py | 9 +++++---- Lib/pathlib/types.py | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Lib/glob.py b/Lib/glob.py index d1a6ddd..8879eff 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -320,11 +320,11 @@ def translate(pat, *, recursive=False, include_hidden=False, seps=None): @functools.lru_cache(maxsize=512) -def _compile_pattern(pat, sep, case_sensitive, recursive=True): +def _compile_pattern(pat, seps, case_sensitive, recursive=True): """Compile given glob pattern to a re.Pattern object (observing case sensitivity).""" flags = re.NOFLAG if case_sensitive else re.IGNORECASE - regex = translate(pat, recursive=recursive, include_hidden=True, seps=sep) + regex = translate(pat, recursive=recursive, include_hidden=True, seps=seps) return re.compile(regex, flags=flags).match @@ -360,8 +360,9 @@ class _GlobberBase: # High-level methods - def compile(self, pat): - return _compile_pattern(pat, self.sep, self.case_sensitive, self.recursive) + def compile(self, pat, altsep=None): + seps = (self.sep, altsep) if altsep else self.sep + return _compile_pattern(pat, seps, self.case_sensitive, self.recursive) def selector(self, parts): """Returns a function that selects from a given path, walking and diff --git a/Lib/pathlib/types.py b/Lib/pathlib/types.py index c65e4e3..67e084c 100644 --- a/Lib/pathlib/types.py +++ b/Lib/pathlib/types.py @@ -14,7 +14,7 @@ from abc import ABC, abstractmethod from glob import _PathGlobber, _no_recurse_symlinks from pathlib import PurePath, Path from pathlib._os import magic_open, ensure_distinct_paths, copy_file -from typing import Protocol, runtime_checkable +from typing import Optional, Protocol, runtime_checkable def _explode_path(path): @@ -44,6 +44,7 @@ class _PathParser(Protocol): """ sep: str + altsep: Optional[str] def split(self, path: str) -> tuple[str, str]: ... def splitext(self, path: str) -> tuple[str, str]: ... def normcase(self, path: str) -> str: ... @@ -225,7 +226,7 @@ class _JoinablePath(ABC): if case_sensitive is None: case_sensitive = self.parser.normcase('Aa') == 'Aa' globber = _PathGlobber(pattern.parser.sep, case_sensitive, recursive=True) - match = globber.compile(str(pattern)) + match = globber.compile(str(pattern), altsep=pattern.parser.altsep) return match(str(self)) is not None -- cgit v0.12