Skip to content

Commit 47e5a50

Browse files
committed
Simplify joined path caching.
1 parent ea98944 commit 47e5a50

File tree

2 files changed

+24
-23
lines changed

2 files changed

+24
-23
lines changed

Lib/pathlib/_abc.py

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,6 @@ class PurePathBase:
116116
# the `__init__()` method.
117117
'_raw_paths',
118118

119-
# The `_str` slot stores the string representation of the path,
120-
# computed when `__str__()` is called for the first time.
121-
'_str',
122-
123119
# The '_resolving' slot stores a boolean indicating whether the path
124120
# is being processed by `PathBase.resolve()`. This prevents duplicate
125121
# work from occurring when `resolve()` calls `stat()` or `readlink()`.
@@ -145,25 +141,22 @@ def with_segments(self, *pathsegments):
145141
"""
146142
return type(self)(*pathsegments)
147143

148-
@property
149-
def _raw_path(self):
150-
paths = self._raw_paths
151-
if len(paths) == 0:
152-
path = ''
153-
elif len(paths) == 1:
154-
path = paths[0]
155-
else:
156-
path = self.parser.join(*paths)
157-
return path
158-
159144
def __str__(self):
160145
"""Return the string representation of the path, suitable for
161146
passing to system calls."""
162-
try:
163-
return self._str
164-
except AttributeError:
165-
self._str = self._raw_path
166-
return self._str
147+
paths = self._raw_paths
148+
if len(paths) == 1:
149+
return paths[0]
150+
elif paths:
151+
# Join path segments from the initializer.
152+
path = self.parser.join(*paths)
153+
# Cache the joined path.
154+
paths.clear()
155+
paths.append(path)
156+
return path
157+
else:
158+
paths.append('')
159+
return ''
167160

168161
def as_posix(self):
169162
"""Return the string representation of the path with forward (/)

Lib/pathlib/_local.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ class PurePath(PurePathBase):
7777
# tail are normalized.
7878
'_drv', '_root', '_tail_cached',
7979

80+
# The `_str` slot stores the string representation of the path,
81+
# computed from the drive, root and tail when `__str__()` is called
82+
# for the first time. It's used to implement `_str_normcase`
83+
'_str',
84+
8085
# The `_str_normcase_cached` slot stores the string path with
8186
# normalized case. It is set when the `_str_normcase` property is
8287
# accessed for the first time. It's used to implement `__eq__()`
@@ -296,7 +301,8 @@ def drive(self):
296301
try:
297302
return self._drv
298303
except AttributeError:
299-
self._drv, self._root, self._tail_cached = self._parse_path(self._raw_path)
304+
raw_path = PurePathBase.__str__(self)
305+
self._drv, self._root, self._tail_cached = self._parse_path(raw_path)
300306
return self._drv
301307

302308
@property
@@ -305,15 +311,17 @@ def root(self):
305311
try:
306312
return self._root
307313
except AttributeError:
308-
self._drv, self._root, self._tail_cached = self._parse_path(self._raw_path)
314+
raw_path = PurePathBase.__str__(self)
315+
self._drv, self._root, self._tail_cached = self._parse_path(raw_path)
309316
return self._root
310317

311318
@property
312319
def _tail(self):
313320
try:
314321
return self._tail_cached
315322
except AttributeError:
316-
self._drv, self._root, self._tail_cached = self._parse_path(self._raw_path)
323+
raw_path = PurePathBase.__str__(self)
324+
self._drv, self._root, self._tail_cached = self._parse_path(raw_path)
317325
return self._tail_cached
318326

319327
@property

0 commit comments

Comments
 (0)