diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py index 287b7b2bc41936..43e6624934b045 100644 --- a/Lib/pathlib/_abc.py +++ b/Lib/pathlib/_abc.py @@ -116,10 +116,6 @@ class PurePathBase: # the `__init__()` method. '_raw_paths', - # The `_str` slot stores the string representation of the path, - # computed when `__str__()` is called for the first time. - '_str', - # The '_resolving' slot stores a boolean indicating whether the path # is being processed by `PathBase.resolve()`. This prevents duplicate # work from occurring when `resolve()` calls `stat()` or `readlink()`. @@ -145,25 +141,22 @@ def with_segments(self, *pathsegments): """ return type(self)(*pathsegments) - @property - def _raw_path(self): - paths = self._raw_paths - if len(paths) == 0: - path = '' - elif len(paths) == 1: - path = paths[0] - else: - path = self.parser.join(*paths) - return path - def __str__(self): """Return the string representation of the path, suitable for passing to system calls.""" - try: - return self._str - except AttributeError: - self._str = self._raw_path - return self._str + 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 '' def as_posix(self): """Return the string representation of the path with forward (/) diff --git a/Lib/pathlib/_local.py b/Lib/pathlib/_local.py index bf52ac4d4c8a8b..b27f456d375225 100644 --- a/Lib/pathlib/_local.py +++ b/Lib/pathlib/_local.py @@ -77,6 +77,11 @@ class PurePath(PurePathBase): # tail are normalized. '_drv', '_root', '_tail_cached', + # The `_str` slot stores the string representation of the path, + # computed from the drive, root and tail when `__str__()` is called + # for the first time. It's used to implement `_str_normcase` + '_str', + # The `_str_normcase_cached` slot stores the string path with # normalized case. It is set when the `_str_normcase` property is # accessed for the first time. It's used to implement `__eq__()` @@ -296,7 +301,8 @@ def drive(self): try: return self._drv except AttributeError: - self._drv, self._root, self._tail_cached = self._parse_path(self._raw_path) + raw_path = PurePathBase.__str__(self) + self._drv, self._root, self._tail_cached = self._parse_path(raw_path) return self._drv @property @@ -305,7 +311,8 @@ def root(self): try: return self._root except AttributeError: - self._drv, self._root, self._tail_cached = self._parse_path(self._raw_path) + raw_path = PurePathBase.__str__(self) + self._drv, self._root, self._tail_cached = self._parse_path(raw_path) return self._root @property @@ -313,7 +320,8 @@ def _tail(self): try: return self._tail_cached except AttributeError: - self._drv, self._root, self._tail_cached = self._parse_path(self._raw_path) + raw_path = PurePathBase.__str__(self) + self._drv, self._root, self._tail_cached = self._parse_path(raw_path) return self._tail_cached @property