summaryrefslogtreecommitdiffstats
path: root/Lib/pathlib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/pathlib')
-rw-r--r--Lib/pathlib/_abc.py40
-rw-r--r--Lib/pathlib/_local.py37
-rw-r--r--Lib/pathlib/_types.py1
3 files changed, 38 insertions, 40 deletions
diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py
index b456029..4402efe 100644
--- a/Lib/pathlib/_abc.py
+++ b/Lib/pathlib/_abc.py
@@ -44,49 +44,25 @@ class PurePathBase:
"""Base class for pure path objects.
This class *does not* provide several magic methods that are defined in
- its subclass PurePath. They are: __fspath__, __bytes__, __reduce__,
- __hash__, __eq__, __lt__, __le__, __gt__, __ge__. Its initializer and path
- joining methods accept only strings, not os.PathLike objects more broadly.
+ its subclass PurePath. They are: __init__, __fspath__, __bytes__,
+ __reduce__, __hash__, __eq__, __lt__, __le__, __gt__, __ge__.
"""
- __slots__ = (
- # The `_raw_paths` slot stores unjoined string paths. This is set in
- # the `__init__()` method.
- '_raw_paths',
- )
+ __slots__ = ()
parser = posixpath
_globber = PathGlobber
- def __init__(self, *args):
- for arg in args:
- if not isinstance(arg, str):
- raise TypeError(
- f"argument should be a str, not {type(arg).__name__!r}")
- self._raw_paths = list(args)
-
def with_segments(self, *pathsegments):
"""Construct a new path object from any number of path-like objects.
Subclasses may override this method to customize how new path objects
are created from methods like `iterdir()`.
"""
- return type(self)(*pathsegments)
+ raise NotImplementedError
def __str__(self):
"""Return the string representation of the path, suitable for
passing to system calls."""
- paths = self._raw_paths
- if len(paths) == 1:
- return paths[0]
- elif paths:
- # Join path segments from the initializer.
- path = self.parser.join(*paths)
- # Cache the joined path.
- paths.clear()
- paths.append(path)
- return path
- else:
- paths.append('')
- return ''
+ raise NotImplementedError
def as_posix(self):
"""Return the string representation of the path with forward (/)
@@ -234,17 +210,17 @@ class PurePathBase:
paths) or a totally different path (if one of the arguments is
anchored).
"""
- return self.with_segments(*self._raw_paths, *pathsegments)
+ return self.with_segments(str(self), *pathsegments)
def __truediv__(self, key):
try:
- return self.with_segments(*self._raw_paths, key)
+ return self.with_segments(str(self), key)
except TypeError:
return NotImplemented
def __rtruediv__(self, key):
try:
- return self.with_segments(key, *self._raw_paths)
+ return self.with_segments(key, str(self))
except TypeError:
return NotImplemented
diff --git a/Lib/pathlib/_local.py b/Lib/pathlib/_local.py
index b933dd5..7689c10 100644
--- a/Lib/pathlib/_local.py
+++ b/Lib/pathlib/_local.py
@@ -77,6 +77,10 @@ class PurePath(PurePathBase):
"""
__slots__ = (
+ # The `_raw_paths` slot stores unjoined string paths. This is set in
+ # the `__init__()` method.
+ '_raw_paths',
+
# The `_drv`, `_root` and `_tail_cached` slots store parsed and
# normalized parts of the path. They are set when any of the `drive`,
# `root` or `_tail` properties are accessed for the first time. The
@@ -140,9 +144,15 @@ class PurePath(PurePathBase):
"object where __fspath__ returns a str, "
f"not {type(path).__name__!r}")
paths.append(path)
- # Avoid calling super().__init__, as an optimisation
self._raw_paths = paths
+ def with_segments(self, *pathsegments):
+ """Construct a new path object from any number of path-like objects.
+ Subclasses may override this method to customize how new path objects
+ are created from methods like `iterdir()`.
+ """
+ return type(self)(*pathsegments)
+
def joinpath(self, *pathsegments):
"""Combine this path with one or several arguments, and return a
new path representing either a subpath (if all arguments are relative
@@ -305,13 +315,28 @@ class PurePath(PurePathBase):
return parts
@property
+ def _raw_path(self):
+ paths = self._raw_paths
+ if len(paths) == 1:
+ return paths[0]
+ elif paths:
+ # Join path segments from the initializer.
+ path = self.parser.join(*paths)
+ # Cache the joined path.
+ paths.clear()
+ paths.append(path)
+ return path
+ else:
+ paths.append('')
+ return ''
+
+ @property
def drive(self):
"""The drive prefix (letter or UNC path), if any."""
try:
return self._drv
except AttributeError:
- raw_path = PurePathBase.__str__(self)
- self._drv, self._root, self._tail_cached = self._parse_path(raw_path)
+ self._drv, self._root, self._tail_cached = self._parse_path(self._raw_path)
return self._drv
@property
@@ -320,8 +345,7 @@ class PurePath(PurePathBase):
try:
return self._root
except AttributeError:
- raw_path = PurePathBase.__str__(self)
- self._drv, self._root, self._tail_cached = self._parse_path(raw_path)
+ self._drv, self._root, self._tail_cached = self._parse_path(self._raw_path)
return self._root
@property
@@ -329,8 +353,7 @@ class PurePath(PurePathBase):
try:
return self._tail_cached
except AttributeError:
- raw_path = PurePathBase.__str__(self)
- self._drv, self._root, self._tail_cached = self._parse_path(raw_path)
+ self._drv, self._root, self._tail_cached = self._parse_path(self._raw_path)
return self._tail_cached
@property
diff --git a/Lib/pathlib/_types.py b/Lib/pathlib/_types.py
index 60df94d..baa4a7e 100644
--- a/Lib/pathlib/_types.py
+++ b/Lib/pathlib/_types.py
@@ -14,7 +14,6 @@ class Parser(Protocol):
"""
sep: str
- def join(self, path: str, *paths: str) -> str: ...
def split(self, path: str) -> tuple[str, str]: ...
def splitdrive(self, path: str) -> tuple[str, str]: ...
def splitext(self, path: str) -> tuple[str, str]: ...