mirror of
https://github.com/python/cpython.git
synced 2025-11-01 10:45:30 +00:00
GH-114575: Rename PurePath.pathmod to PurePath.parser (#116513)
And rename the private base class from `PathModuleBase` to `ParserBase`.
This commit is contained in:
parent
bfc57d43d8
commit
752e18389e
6 changed files with 123 additions and 119 deletions
|
|
@ -110,7 +110,7 @@ class PurePath(_abc.PurePathBase):
|
|||
# path. It's set when `__hash__()` is called for the first time.
|
||||
'_hash',
|
||||
)
|
||||
pathmod = os.path
|
||||
parser = os.path
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
"""Construct a PurePath from one or several strings and or existing
|
||||
|
|
@ -126,7 +126,7 @@ class PurePath(_abc.PurePathBase):
|
|||
paths = []
|
||||
for arg in args:
|
||||
if isinstance(arg, PurePath):
|
||||
if arg.pathmod is ntpath and self.pathmod is posixpath:
|
||||
if arg.parser is ntpath and self.parser is posixpath:
|
||||
# GH-103631: Convert separators for backwards compatibility.
|
||||
paths.extend(path.replace('\\', '/') for path in arg._raw_paths)
|
||||
else:
|
||||
|
|
@ -187,7 +187,7 @@ class PurePath(_abc.PurePathBase):
|
|||
try:
|
||||
return self._str_normcase_cached
|
||||
except AttributeError:
|
||||
if _abc._is_case_sensitive(self.pathmod):
|
||||
if _abc._is_case_sensitive(self.parser):
|
||||
self._str_normcase_cached = str(self)
|
||||
else:
|
||||
self._str_normcase_cached = str(self).lower()
|
||||
|
|
@ -203,7 +203,7 @@ class PurePath(_abc.PurePathBase):
|
|||
def __eq__(self, other):
|
||||
if not isinstance(other, PurePath):
|
||||
return NotImplemented
|
||||
return self._str_normcase == other._str_normcase and self.pathmod is other.pathmod
|
||||
return self._str_normcase == other._str_normcase and self.parser is other.parser
|
||||
|
||||
@property
|
||||
def _parts_normcase(self):
|
||||
|
|
@ -211,26 +211,26 @@ class PurePath(_abc.PurePathBase):
|
|||
try:
|
||||
return self._parts_normcase_cached
|
||||
except AttributeError:
|
||||
self._parts_normcase_cached = self._str_normcase.split(self.pathmod.sep)
|
||||
self._parts_normcase_cached = self._str_normcase.split(self.parser.sep)
|
||||
return self._parts_normcase_cached
|
||||
|
||||
def __lt__(self, other):
|
||||
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
||||
if not isinstance(other, PurePath) or self.parser is not other.parser:
|
||||
return NotImplemented
|
||||
return self._parts_normcase < other._parts_normcase
|
||||
|
||||
def __le__(self, other):
|
||||
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
||||
if not isinstance(other, PurePath) or self.parser is not other.parser:
|
||||
return NotImplemented
|
||||
return self._parts_normcase <= other._parts_normcase
|
||||
|
||||
def __gt__(self, other):
|
||||
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
||||
if not isinstance(other, PurePath) or self.parser is not other.parser:
|
||||
return NotImplemented
|
||||
return self._parts_normcase > other._parts_normcase
|
||||
|
||||
def __ge__(self, other):
|
||||
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
||||
if not isinstance(other, PurePath) or self.parser is not other.parser:
|
||||
return NotImplemented
|
||||
return self._parts_normcase >= other._parts_normcase
|
||||
|
||||
|
|
@ -247,10 +247,10 @@ class PurePath(_abc.PurePathBase):
|
|||
@classmethod
|
||||
def _format_parsed_parts(cls, drv, root, tail):
|
||||
if drv or root:
|
||||
return drv + root + cls.pathmod.sep.join(tail)
|
||||
elif tail and cls.pathmod.splitdrive(tail[0])[0]:
|
||||
return drv + root + cls.parser.sep.join(tail)
|
||||
elif tail and cls.parser.splitdrive(tail[0])[0]:
|
||||
tail = ['.'] + tail
|
||||
return cls.pathmod.sep.join(tail)
|
||||
return cls.parser.sep.join(tail)
|
||||
|
||||
def _from_parsed_parts(self, drv, root, tail):
|
||||
path_str = self._format_parsed_parts(drv, root, tail)
|
||||
|
|
@ -265,11 +265,11 @@ class PurePath(_abc.PurePathBase):
|
|||
def _parse_path(cls, path):
|
||||
if not path:
|
||||
return '', '', []
|
||||
sep = cls.pathmod.sep
|
||||
altsep = cls.pathmod.altsep
|
||||
sep = cls.parser.sep
|
||||
altsep = cls.parser.altsep
|
||||
if altsep:
|
||||
path = path.replace(altsep, sep)
|
||||
drv, root, rel = cls.pathmod.splitroot(path)
|
||||
drv, root, rel = cls.parser.splitroot(path)
|
||||
if not root and drv.startswith(sep) and not drv.endswith(sep):
|
||||
drv_parts = drv.split(sep)
|
||||
if len(drv_parts) == 4 and drv_parts[2] not in '?.':
|
||||
|
|
@ -290,7 +290,7 @@ class PurePath(_abc.PurePathBase):
|
|||
elif len(paths) == 1:
|
||||
path = paths[0]
|
||||
else:
|
||||
path = self.pathmod.join(*paths)
|
||||
path = self.parser.join(*paths)
|
||||
return path
|
||||
|
||||
@property
|
||||
|
|
@ -360,8 +360,8 @@ class PurePath(_abc.PurePathBase):
|
|||
|
||||
def with_name(self, name):
|
||||
"""Return a new path with the file name changed."""
|
||||
m = self.pathmod
|
||||
if not name or m.sep in name or (m.altsep and m.altsep in name) or name == '.':
|
||||
p = self.parser
|
||||
if not name or p.sep in name or (p.altsep and p.altsep in name) or name == '.':
|
||||
raise ValueError(f"Invalid name {name!r}")
|
||||
tail = self._tail.copy()
|
||||
if not tail:
|
||||
|
|
@ -413,13 +413,13 @@ class PurePath(_abc.PurePathBase):
|
|||
def is_absolute(self):
|
||||
"""True if the path is absolute (has both a root and, if applicable,
|
||||
a drive)."""
|
||||
if self.pathmod is posixpath:
|
||||
if self.parser is posixpath:
|
||||
# Optimization: work with raw paths on POSIX.
|
||||
for path in self._raw_paths:
|
||||
if path.startswith('/'):
|
||||
return True
|
||||
return False
|
||||
return self.pathmod.isabs(self)
|
||||
return self.parser.isabs(self)
|
||||
|
||||
def is_reserved(self):
|
||||
"""Return True if the path contains one of the special names reserved
|
||||
|
|
@ -428,8 +428,8 @@ class PurePath(_abc.PurePathBase):
|
|||
"for removal in Python 3.15. Use os.path.isreserved() to "
|
||||
"detect reserved paths on Windows.")
|
||||
warnings.warn(msg, DeprecationWarning, stacklevel=2)
|
||||
if self.pathmod is ntpath:
|
||||
return self.pathmod.isreserved(self)
|
||||
if self.parser is ntpath:
|
||||
return self.parser.isreserved(self)
|
||||
return False
|
||||
|
||||
def as_uri(self):
|
||||
|
|
@ -462,7 +462,7 @@ class PurePath(_abc.PurePathBase):
|
|||
raise NotImplementedError("Non-relative patterns are unsupported")
|
||||
elif not parts:
|
||||
raise ValueError("Unacceptable pattern: {!r}".format(pattern))
|
||||
elif pattern[-1] in (self.pathmod.sep, self.pathmod.altsep):
|
||||
elif pattern[-1] in (self.parser.sep, self.parser.altsep):
|
||||
# GH-65238: pathlib doesn't preserve trailing slash. Add it back.
|
||||
parts.append('')
|
||||
parts.reverse()
|
||||
|
|
@ -487,7 +487,7 @@ class PurePosixPath(PurePath):
|
|||
On a POSIX system, instantiating a PurePath should return this object.
|
||||
However, you can also instantiate it directly on any system.
|
||||
"""
|
||||
pathmod = posixpath
|
||||
parser = posixpath
|
||||
__slots__ = ()
|
||||
|
||||
|
||||
|
|
@ -497,7 +497,7 @@ class PureWindowsPath(PurePath):
|
|||
On a Windows system, instantiating a PurePath should return this object.
|
||||
However, you can also instantiate it directly on any system.
|
||||
"""
|
||||
pathmod = ntpath
|
||||
parser = ntpath
|
||||
__slots__ = ()
|
||||
|
||||
|
||||
|
|
@ -607,7 +607,7 @@ class Path(_abc.PathBase, PurePath):
|
|||
path_str = str(self)
|
||||
tail = self._tail
|
||||
if tail:
|
||||
path_str = f'{path_str}{self.pathmod.sep}{name}'
|
||||
path_str = f'{path_str}{self.parser.sep}{name}'
|
||||
elif path_str != '.':
|
||||
path_str = f'{path_str}{name}'
|
||||
else:
|
||||
|
|
@ -675,7 +675,7 @@ class Path(_abc.PathBase, PurePath):
|
|||
drive, root, rel = os.path.splitroot(cwd)
|
||||
if not rel:
|
||||
return self._from_parsed_parts(drive, root, self._tail)
|
||||
tail = rel.split(self.pathmod.sep)
|
||||
tail = rel.split(self.parser.sep)
|
||||
tail.extend(self._tail)
|
||||
return self._from_parsed_parts(drive, root, tail)
|
||||
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ def _ignore_error(exception):
|
|||
|
||||
|
||||
@functools.cache
|
||||
def _is_case_sensitive(pathmod):
|
||||
return pathmod.normcase('Aa') == 'Aa'
|
||||
def _is_case_sensitive(parser):
|
||||
return parser.normcase('Aa') == 'Aa'
|
||||
|
||||
#
|
||||
# Globbing helpers
|
||||
|
|
@ -156,12 +156,12 @@ class UnsupportedOperation(NotImplementedError):
|
|||
pass
|
||||
|
||||
|
||||
class PathModuleBase:
|
||||
"""Base class for path modules, which do low-level path manipulation.
|
||||
class ParserBase:
|
||||
"""Base class for path parsers, which do low-level path manipulation.
|
||||
|
||||
Path modules provide a subset of the os.path API, specifically those
|
||||
Path parsers provide a subset of the os.path API, specifically those
|
||||
functions needed to provide PurePathBase functionality. Each PurePathBase
|
||||
subclass references its path module via a 'pathmod' class attribute.
|
||||
subclass references its path parser via a 'parser' class attribute.
|
||||
|
||||
Every method in this base class raises an UnsupportedOperation exception.
|
||||
"""
|
||||
|
|
@ -221,10 +221,10 @@ class PurePathBase:
|
|||
# work from occurring when `resolve()` calls `stat()` or `readlink()`.
|
||||
'_resolving',
|
||||
)
|
||||
pathmod = PathModuleBase()
|
||||
parser = ParserBase()
|
||||
|
||||
def __init__(self, path, *paths):
|
||||
self._raw_path = self.pathmod.join(path, *paths) if paths else path
|
||||
self._raw_path = self.parser.join(path, *paths) if paths else path
|
||||
if not isinstance(self._raw_path, str):
|
||||
raise TypeError(
|
||||
f"path should be a str, not {type(self._raw_path).__name__!r}")
|
||||
|
|
@ -245,17 +245,17 @@ class PurePathBase:
|
|||
def as_posix(self):
|
||||
"""Return the string representation of the path with forward (/)
|
||||
slashes."""
|
||||
return str(self).replace(self.pathmod.sep, '/')
|
||||
return str(self).replace(self.parser.sep, '/')
|
||||
|
||||
@property
|
||||
def drive(self):
|
||||
"""The drive prefix (letter or UNC path), if any."""
|
||||
return self.pathmod.splitdrive(self.anchor)[0]
|
||||
return self.parser.splitdrive(self.anchor)[0]
|
||||
|
||||
@property
|
||||
def root(self):
|
||||
"""The root of the path, if any."""
|
||||
return self.pathmod.splitdrive(self.anchor)[1]
|
||||
return self.parser.splitdrive(self.anchor)[1]
|
||||
|
||||
@property
|
||||
def anchor(self):
|
||||
|
|
@ -265,7 +265,7 @@ class PurePathBase:
|
|||
@property
|
||||
def name(self):
|
||||
"""The final path component, if any."""
|
||||
return self.pathmod.split(self._raw_path)[1]
|
||||
return self.parser.split(self._raw_path)[1]
|
||||
|
||||
@property
|
||||
def suffix(self):
|
||||
|
|
@ -306,7 +306,7 @@ class PurePathBase:
|
|||
|
||||
def with_name(self, name):
|
||||
"""Return a new path with the file name changed."""
|
||||
split = self.pathmod.split
|
||||
split = self.parser.split
|
||||
if split(name)[0]:
|
||||
raise ValueError(f"Invalid name {name!r}")
|
||||
return self.with_segments(split(self._raw_path)[0], name)
|
||||
|
|
@ -419,7 +419,7 @@ class PurePathBase:
|
|||
uppermost parent of the path (equivalent to path.parents[-1]), and
|
||||
*parts* is a reversed list of parts following the anchor.
|
||||
"""
|
||||
split = self.pathmod.split
|
||||
split = self.parser.split
|
||||
path = self._raw_path
|
||||
parent, name = split(path)
|
||||
names = []
|
||||
|
|
@ -433,7 +433,7 @@ class PurePathBase:
|
|||
def parent(self):
|
||||
"""The logical parent of the path."""
|
||||
path = self._raw_path
|
||||
parent = self.pathmod.split(path)[0]
|
||||
parent = self.parser.split(path)[0]
|
||||
if path != parent:
|
||||
parent = self.with_segments(parent)
|
||||
parent._resolving = self._resolving
|
||||
|
|
@ -443,7 +443,7 @@ class PurePathBase:
|
|||
@property
|
||||
def parents(self):
|
||||
"""A sequence of this path's logical parents."""
|
||||
split = self.pathmod.split
|
||||
split = self.parser.split
|
||||
path = self._raw_path
|
||||
parent = split(path)[0]
|
||||
parents = []
|
||||
|
|
@ -456,7 +456,7 @@ class PurePathBase:
|
|||
def is_absolute(self):
|
||||
"""True if the path is absolute (has both a root and, if applicable,
|
||||
a drive)."""
|
||||
return self.pathmod.isabs(self._raw_path)
|
||||
return self.parser.isabs(self._raw_path)
|
||||
|
||||
@property
|
||||
def _pattern_stack(self):
|
||||
|
|
@ -481,8 +481,8 @@ class PurePathBase:
|
|||
if not isinstance(path_pattern, PurePathBase):
|
||||
path_pattern = self.with_segments(path_pattern)
|
||||
if case_sensitive is None:
|
||||
case_sensitive = _is_case_sensitive(self.pathmod)
|
||||
sep = path_pattern.pathmod.sep
|
||||
case_sensitive = _is_case_sensitive(self.parser)
|
||||
sep = path_pattern.parser.sep
|
||||
path_parts = self.parts[::-1]
|
||||
pattern_parts = path_pattern.parts[::-1]
|
||||
if not pattern_parts:
|
||||
|
|
@ -505,8 +505,8 @@ class PurePathBase:
|
|||
if not isinstance(pattern, PurePathBase):
|
||||
pattern = self.with_segments(pattern)
|
||||
if case_sensitive is None:
|
||||
case_sensitive = _is_case_sensitive(self.pathmod)
|
||||
match = _compile_pattern(pattern._pattern_str, pattern.pathmod.sep, case_sensitive)
|
||||
case_sensitive = _is_case_sensitive(self.parser)
|
||||
match = _compile_pattern(pattern._pattern_str, pattern.parser.sep, case_sensitive)
|
||||
return match(self._pattern_str) is not None
|
||||
|
||||
|
||||
|
|
@ -797,12 +797,12 @@ class PathBase(PurePathBase):
|
|||
pattern = self.with_segments(pattern)
|
||||
if case_sensitive is None:
|
||||
# TODO: evaluate case-sensitivity of each directory in _select_children().
|
||||
case_sensitive = _is_case_sensitive(self.pathmod)
|
||||
case_sensitive = _is_case_sensitive(self.parser)
|
||||
|
||||
stack = pattern._pattern_stack
|
||||
specials = ('', '.', '..')
|
||||
deduplicate_paths = False
|
||||
sep = self.pathmod.sep
|
||||
sep = self.parser.sep
|
||||
paths = iter([self] if self.is_dir() else [])
|
||||
while stack:
|
||||
part = stack.pop()
|
||||
|
|
@ -973,7 +973,7 @@ class PathBase(PurePathBase):
|
|||
continue
|
||||
path_tail.append(part)
|
||||
if querying and part != '..':
|
||||
path = self.with_segments(path_root + self.pathmod.sep.join(path_tail))
|
||||
path = self.with_segments(path_root + self.parser.sep.join(path_tail))
|
||||
path._resolving = True
|
||||
try:
|
||||
st = path.stat(follow_symlinks=False)
|
||||
|
|
@ -1002,7 +1002,7 @@ class PathBase(PurePathBase):
|
|||
raise
|
||||
else:
|
||||
querying = False
|
||||
return self.with_segments(path_root + self.pathmod.sep.join(path_tail))
|
||||
return self.with_segments(path_root + self.parser.sep.join(path_tail))
|
||||
|
||||
def symlink_to(self, target, target_is_directory=False):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue