]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-112727: Speed up `pathlib.Path.absolute()` (#112728)
authorBarney Gale <barney.gale@gmail.com>
Mon, 4 Dec 2023 23:21:39 +0000 (23:21 +0000)
committerGitHub <noreply@github.com>
Mon, 4 Dec 2023 23:21:39 +0000 (23:21 +0000)
Use `_from_parsed_parts()` to create a pre-joined/pre-parsed path, rather
than passing multiple arguments to `with_segments()`

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Lib/pathlib.py
Misc/NEWS.d/next/Library/2023-12-04-21-30-34.gh-issue-112727.jpgNRB.rst [new file with mode: 0644]

index b728a0b3dfdb6c422c152925494b4359a412c0a7..c48cff307083a81f0cd718a4a68262e7f21a5867 100644 (file)
@@ -1415,21 +1415,29 @@ class Path(_PathBase):
         """
         if self.is_absolute():
             return self
-        elif self.drive:
+        if self.root:
+            drive = os.path.splitroot(os.getcwd())[0]
+            return self._from_parsed_parts(drive, self.root, self._tail)
+        if self.drive:
             # There is a CWD on each drive-letter drive.
             cwd = os.path.abspath(self.drive)
         else:
             cwd = os.getcwd()
+        if not self._tail:
             # Fast path for "empty" paths, e.g. Path("."), Path("") or Path().
             # We pass only one argument to with_segments() to avoid the cost
             # of joining, and we exploit the fact that getcwd() returns a
             # fully-normalized string by storing it in _str. This is used to
             # implement Path.cwd().
-            if not self.root and not self._tail:
-                result = self.with_segments(cwd)
-                result._str = cwd
-                return result
-        return self.with_segments(cwd, self)
+            result = self.with_segments(cwd)
+            result._str = cwd
+            return result
+        drive, root, rel = os.path.splitroot(cwd)
+        if not rel:
+            return self._from_parsed_parts(drive, root, self._tail)
+        tail = rel.split(self.pathmod.sep)
+        tail.extend(self._tail)
+        return self._from_parsed_parts(drive, root, tail)
 
     def resolve(self, strict=False):
         """
diff --git a/Misc/NEWS.d/next/Library/2023-12-04-21-30-34.gh-issue-112727.jpgNRB.rst b/Misc/NEWS.d/next/Library/2023-12-04-21-30-34.gh-issue-112727.jpgNRB.rst
new file mode 100644 (file)
index 0000000..bbe7aae
--- /dev/null
@@ -0,0 +1 @@
+Speed up :meth:`pathlib.Path.absolute`. Patch by Barney Gale.