◐ Shell
clean mode source ↗

bpo-44136: pathlib: merge `_Flavour.is_reserved()` into `PurePath.is_reserved()` by barneygale · Pull Request #30321 · python/cpython

Expand Up @@ -35,6 +35,12 @@ _WINERROR_INVALID_NAME, _WINERROR_CANT_RESOLVE_FILENAME)
_WIN_RESERVED_NAMES = ( {'CON', 'PRN', 'AUX', 'NUL', 'CONIN$', 'CONOUT$'} | {f'COM{c}' for c in '123456789\xb9\xb2\xb3'} | {f'LPT{c}' for c in '123456789\xb9\xb2\xb3'} )
def _ignore_error(exception): return (getattr(exception, 'errno', None) in _IGNORED_ERRNOS or getattr(exception, 'winerror', None) in _IGNORED_WINERRORS) Expand Down Expand Up @@ -123,11 +129,6 @@ class _WindowsFlavour(_Flavour): drive_letters = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') ext_namespace_prefix = '\\\\?\\'
reserved_names = ( {'CON', 'PRN', 'AUX', 'NUL', 'CONIN$', 'CONOUT$'} | {'COM%s' % c for c in '123456789\xb9\xb2\xb3'} | {'LPT%s' % c for c in '123456789\xb9\xb2\xb3'} )
# Interesting findings about extended paths: # * '\\?\c:\a' is an extended path, which bypasses normal Windows API Expand Down Expand Up @@ -202,19 +203,6 @@ def _split_extended_path(self, s, ext_prefix=ext_namespace_prefix): s = '\\' + s[3:] return prefix, s
def is_reserved(self, parts): # NOTE: the rules for reserved names seem somewhat complicated # (e.g. r"..\NUL" is reserved but not r"foo\NUL" if "foo" does not # exist). We err on the side of caution and return True for paths # which are not considered reserved by Windows. if not parts: return False if parts[0].startswith('\\\\'): # UNC paths are never reserved return False name = parts[-1].partition('.')[0].partition(':')[0].rstrip(' ') return name.upper() in self.reserved_names
def make_uri(self, path): # Under Windows, file URIs use the UTF-8 encoding. drive = path.drive Expand Down Expand Up @@ -260,9 +248,6 @@ def casefold_parts(self, parts): def compile_pattern(self, pattern): return re.compile(fnmatch.translate(pattern)).fullmatch
def is_reserved(self, parts): return False
def make_uri(self, path): # We represent the path using the local filesystem encoding, # for portability to other applications. Expand Down Expand Up @@ -885,7 +870,7 @@ def is_absolute(self): def is_reserved(self): """Return True if the path contains one of the special names reserved by the system, if any.""" return self._flavour.is_reserved(self._parts) return False
def match(self, path_pattern): """ Expand Down Expand Up @@ -936,6 +921,20 @@ class PureWindowsPath(PurePath): _flavour = _windows_flavour __slots__ = ()
def is_reserved(self): # NOTE: the rules for reserved names seem somewhat complicated # (e.g. r"..\NUL" is reserved but not r"foo\NUL" if "foo" does not # exist). We err on the side of caution and return True for paths # which are not considered reserved by Windows. parts = self._parts if not parts: return False if parts[0].startswith('\\\\'): # UNC paths are never reserved return False name = parts[-1].partition('.')[0].partition(':')[0].rstrip(' ') return name.upper() in _WIN_RESERVED_NAMES

# Filesystem-accessing classes
Expand Down