Skip to content

Commit

Permalink
Simplify joined path caching.
Browse files Browse the repository at this point in the history
  • Loading branch information
barneygale committed Nov 4, 2024
1 parent ea98944 commit 47e5a50
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 23 deletions.
33 changes: 13 additions & 20 deletions Lib/pathlib/_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()`.
Expand All @@ -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 (/)
Expand Down
14 changes: 11 additions & 3 deletions Lib/pathlib/_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__()`
Expand Down Expand Up @@ -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
Expand All @@ -305,15 +311,17 @@ 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
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
Expand Down

0 comments on commit 47e5a50

Please sign in to comment.