https://github.com/python/cpython/commit/1e914ad89de707b8a69b03d7b36f5022f4c07c78
commit: 1e914ad89de707b8a69b03d7b36f5022f4c07c78
branch: main
author: Barney Gale <[email protected]>
committer: barneygale <[email protected]>
date: 2024-01-06T20:50:25Z
summary:

GH-113528: Deoptimise `pathlib._abc.PurePathBase.name` (#113531)

Replace usage of `_from_parsed_parts()` with `with_segments()` in
`with_name()`, and take a similar approach in `name` for consistency's
sake.

files:
M Lib/pathlib/__init__.py
M Lib/pathlib/_abc.py

diff --git a/Lib/pathlib/__init__.py b/Lib/pathlib/__init__.py
index 115ccf78e3befe..765a1425d0305a 100644
--- a/Lib/pathlib/__init__.py
+++ b/Lib/pathlib/__init__.py
@@ -166,6 +166,25 @@ def __ge__(self, other):
             return NotImplemented
         return self._parts_normcase >= other._parts_normcase
 
+    @property
+    def name(self):
+        """The final path component, if any."""
+        tail = self._tail
+        if not tail:
+            return ''
+        return tail[-1]
+
+    def with_name(self, name):
+        """Return a new path with the file name changed."""
+        m = self.pathmod
+        if not name or m.sep in name or (m.altsep and m.altsep in name) or 
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 relative_to(self, other, /, *_deprecated, walk_up=False):
         """Return the relative path to another path identified by the passed
         arguments.  If the operation is not possible (because this is not
diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py
index b1204e88044a3f..1ce371308827fd 100644
--- a/Lib/pathlib/_abc.py
+++ b/Lib/pathlib/_abc.py
@@ -313,10 +313,10 @@ def anchor(self):
     @property
     def name(self):
         """The final path component, if any."""
-        tail = self._tail
-        if not tail:
+        path_str = str(self)
+        if not path_str or path_str == '.':
             return ''
-        return tail[-1]
+        return self.pathmod.basename(path_str)
 
     @property
     def suffix(self):
@@ -360,11 +360,10 @@ def with_name(self, name):
         m = self.pathmod
         if not name or m.sep in name or (m.altsep and m.altsep in name) or 
name == '.':
             raise ValueError(f"Invalid name {name!r}")
-        tail = self._tail.copy()
-        if not tail:
+        parent, old_name = m.split(str(self))
+        if not old_name or old_name == '.':
             raise ValueError(f"{self!r} has an empty name")
-        tail[-1] = name
-        return self._from_parsed_parts(self.drive, self.root, tail)
+        return self.with_segments(parent, name)
 
     def with_stem(self, stem):
         """Return a new path with the stem changed."""

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to