diff options
author | Barney Gale <barney.gale@gmail.com> | 2023-11-25 17:19:38 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-25 17:19:38 (GMT) |
commit | 19a1fc1b3df30f64450d157dc3a5d40c992e347f (patch) | |
tree | 347f7abd5eb38070f713b2d5f32e1e2a792590d5 /Lib | |
parent | 6b961b8ceaba372b78d03feaceb4837bf7236694 (diff) | |
download | cpython-19a1fc1b3df30f64450d157dc3a5d40c992e347f.zip cpython-19a1fc1b3df30f64450d157dc3a5d40c992e347f.tar.gz cpython-19a1fc1b3df30f64450d157dc3a5d40c992e347f.tar.bz2 |
GH-112361: Speed up pathlib by removing some temporary objects. (#112362)
Construct only one new list object (using `list.copy()`) when creating a
new path object with a modified tail. This slightly speeds up
`with_name()` and `with_suffix()`
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/pathlib.py | 32 | ||||
-rw-r--r-- | Lib/test/test_pathlib.py | 2 |
2 files changed, 12 insertions, 22 deletions
diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 9bce532..32ccf81 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -400,13 +400,14 @@ class PurePath: def with_name(self, name): """Return a new path with the file name changed.""" - if not self.name: - raise ValueError("%r has an empty name" % (self,)) m = self.pathmod if not name or m.sep in name or (m.altsep and m.altsep in name) or name == '.': - raise ValueError("Invalid name %r" % (name)) - return self._from_parsed_parts(self.drive, self.root, - self._tail[:-1] + [name]) + raise ValueError(f"Invalid name {name!r}") + tail = self._tail.copy() + if not tail: + raise ValueError(f"{self!r} has an empty name") + tail[-1] = name + return self._from_parsed_parts(self.drive, self.root, tail) def with_stem(self, stem): """Return a new path with the stem changed.""" @@ -417,21 +418,12 @@ class PurePath: has no suffix, add given suffix. If the given suffix is an empty string, remove the suffix from the path. """ - m = self.pathmod - if m.sep in suffix or m.altsep and m.altsep in suffix: - raise ValueError("Invalid suffix %r" % (suffix,)) - if suffix and not suffix.startswith('.') or suffix == '.': - raise ValueError("Invalid suffix %r" % (suffix)) - name = self.name - if not name: - raise ValueError("%r has an empty name" % (self,)) - old_suffix = self.suffix - if not old_suffix: - name = name + suffix + if not suffix: + return self.with_name(self.stem) + elif suffix.startswith('.') and len(suffix) > 1: + return self.with_name(self.stem + suffix) else: - name = name[:-len(old_suffix)] + suffix - return self._from_parsed_parts(self.drive, self.root, - self._tail[:-1] + [name]) + raise ValueError(f"Invalid suffix {suffix!r}") def relative_to(self, other, /, *_deprecated, walk_up=False): """Return the relative path to another path identified by the passed @@ -1029,7 +1021,7 @@ class _PathBase(PurePath): elif not path_pattern._tail: raise ValueError("Unacceptable pattern: {!r}".format(pattern)) - pattern_parts = list(path_pattern._tail) + pattern_parts = path_pattern._tail.copy() if pattern[-1] in (self.pathmod.sep, self.pathmod.altsep): # GH-65238: pathlib doesn't preserve trailing slash. Add it back. pattern_parts.append('') diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index e1121a9..427e082 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -575,8 +575,6 @@ class PurePathTest(unittest.TestCase): self.assertRaises(ValueError, P('a/b').with_suffix, '.c/.d') self.assertRaises(ValueError, P('a/b').with_suffix, './.d') self.assertRaises(ValueError, P('a/b').with_suffix, '.d/.') - self.assertRaises(ValueError, P('a/b').with_suffix, - (self.pathmod.sep, 'd')) def test_relative_to_common(self): P = self.cls |