mirror of
https://github.com/python/cpython.git
synced 2025-10-17 20:28:43 +00:00
GH-128520: Divide pathlib ABCs into three classes (#128523)
In the private pathlib ABCs, rename `PurePathBase` to `JoinablePath`, and split `PathBase` into `ReadablePath` and `WritablePath`. This improves the API fit for read-only virtual filesystems. The split of `PathBase` entails a similar split of `CopyWorker` (implements copying) and the test cases in `test_pathlib_abc`. In a later patch, we'll make `WritablePath` inherit directly from `JoinablePath` rather than `ReadablePath`. For a couple of reasons, this isn't quite possible yet.
This commit is contained in:
parent
0946ed25b5
commit
22a442181d
5 changed files with 317 additions and 307 deletions
|
@ -20,7 +20,7 @@ except ImportError:
|
|||
grp = None
|
||||
|
||||
from pathlib._os import copyfile
|
||||
from pathlib._abc import CopyWorker, PurePathBase, PathBase
|
||||
from pathlib._abc import CopyWriter, JoinablePath, WritablePath
|
||||
|
||||
|
||||
__all__ = [
|
||||
|
@ -65,7 +65,7 @@ class _PathParents(Sequence):
|
|||
return "<{}.parents>".format(type(self._path).__name__)
|
||||
|
||||
|
||||
class _LocalCopyWorker(CopyWorker):
|
||||
class _LocalCopyWriter(CopyWriter):
|
||||
"""This object implements the Path.copy callable. Don't try to construct
|
||||
it yourself."""
|
||||
__slots__ = ()
|
||||
|
@ -158,7 +158,7 @@ class _LocalCopyWorker(CopyWorker):
|
|||
try:
|
||||
source = os.fspath(source)
|
||||
except TypeError:
|
||||
if not isinstance(source, PathBase):
|
||||
if not isinstance(source, WritablePath):
|
||||
raise
|
||||
super()._create_file(source, metakeys)
|
||||
else:
|
||||
|
@ -190,7 +190,7 @@ class _LocalCopyWorker(CopyWorker):
|
|||
raise err
|
||||
|
||||
|
||||
class PurePath(PurePathBase):
|
||||
class PurePath(JoinablePath):
|
||||
"""Base class for manipulating paths without I/O.
|
||||
|
||||
PurePath represents a filesystem path and offers operations which
|
||||
|
@ -646,7 +646,7 @@ class PurePath(PurePathBase):
|
|||
Return True if this path matches the given glob-style pattern. The
|
||||
pattern is matched against the entire path.
|
||||
"""
|
||||
if not isinstance(pattern, PurePathBase):
|
||||
if not isinstance(pattern, PurePath):
|
||||
pattern = self.with_segments(pattern)
|
||||
if case_sensitive is None:
|
||||
case_sensitive = self.parser is posixpath
|
||||
|
@ -683,7 +683,7 @@ class PureWindowsPath(PurePath):
|
|||
__slots__ = ()
|
||||
|
||||
|
||||
class Path(PathBase, PurePath):
|
||||
class Path(WritablePath, PurePath):
|
||||
"""PurePath subclass that can make system calls.
|
||||
|
||||
Path represents a filesystem path but unlike PurePath, also offers
|
||||
|
@ -830,7 +830,7 @@ class Path(PathBase, PurePath):
|
|||
# Call io.text_encoding() here to ensure any warning is raised at an
|
||||
# appropriate stack level.
|
||||
encoding = io.text_encoding(encoding)
|
||||
return PathBase.read_text(self, encoding, errors, newline)
|
||||
return super().read_text(encoding, errors, newline)
|
||||
|
||||
def write_text(self, data, encoding=None, errors=None, newline=None):
|
||||
"""
|
||||
|
@ -839,7 +839,7 @@ class Path(PathBase, PurePath):
|
|||
# Call io.text_encoding() here to ensure any warning is raised at an
|
||||
# appropriate stack level.
|
||||
encoding = io.text_encoding(encoding)
|
||||
return PathBase.write_text(self, data, encoding, errors, newline)
|
||||
return super().write_text(data, encoding, errors, newline)
|
||||
|
||||
_remove_leading_dot = operator.itemgetter(slice(2, None))
|
||||
_remove_trailing_slash = operator.itemgetter(slice(-1))
|
||||
|
@ -1122,7 +1122,7 @@ class Path(PathBase, PurePath):
|
|||
os.replace(self, target)
|
||||
return self.with_segments(target)
|
||||
|
||||
copy = property(_LocalCopyWorker, doc=_LocalCopyWorker.__call__.__doc__)
|
||||
copy = property(_LocalCopyWriter, doc=_LocalCopyWriter.__call__.__doc__)
|
||||
|
||||
def move(self, target):
|
||||
"""
|
||||
|
@ -1134,7 +1134,7 @@ class Path(PathBase, PurePath):
|
|||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
if not isinstance(target, PathBase):
|
||||
if not isinstance(target, WritablePath):
|
||||
target = self.with_segments(target_str)
|
||||
target.copy._ensure_different_file(self)
|
||||
try:
|
||||
|
@ -1155,7 +1155,7 @@ class Path(PathBase, PurePath):
|
|||
name = self.name
|
||||
if not name:
|
||||
raise ValueError(f"{self!r} has an empty name")
|
||||
elif isinstance(target_dir, PathBase):
|
||||
elif isinstance(target_dir, WritablePath):
|
||||
target = target_dir / name
|
||||
else:
|
||||
target = self.with_segments(target_dir, name)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue