diff options
Diffstat (limited to 'Lib/pathlib')
-rw-r--r-- | Lib/pathlib/_abc.py | 40 | ||||
-rw-r--r-- | Lib/pathlib/_local.py | 37 | ||||
-rw-r--r-- | Lib/pathlib/_types.py | 1 |
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]: ... |