https://github.com/python/cpython/commit/a7711a2a4e5cf16b34fc284085da724a8c2c06dd
commit: a7711a2a4e5cf16b34fc284085da724a8c2c06dd
branch: main
author: Nice Zombies <[email protected]>
committer: zooba <[email protected]>
date: 2024-05-01T22:44:55+01:00
summary:

gh-117607: Speedup os.path.relpath() (GH-117608)

files:
A Misc/NEWS.d/next/Core and 
Builtins/2024-04-07-18-42-09.gh-issue-117607.C978BD.rst
M Lib/ntpath.py
M Lib/posixpath.py

diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index e810b655e5ac85..b833e0bad2645f 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -805,6 +805,9 @@ def realpath(path, *, strict=False):
 def relpath(path, start=None):
     """Return a relative version of a path"""
     path = os.fspath(path)
+    if not path:
+        raise ValueError("no path specified")
+
     if isinstance(path, bytes):
         sep = b'\\'
         curdir = b'.'
@@ -816,22 +819,20 @@ def relpath(path, start=None):
 
     if start is None:
         start = curdir
+    else:
+        start = os.fspath(start)
 
-    if not path:
-        raise ValueError("no path specified")
-
-    start = os.fspath(start)
     try:
-        start_abs = abspath(normpath(start))
-        path_abs = abspath(normpath(path))
+        start_abs = abspath(start)
+        path_abs = abspath(path)
         start_drive, _, start_rest = splitroot(start_abs)
         path_drive, _, path_rest = splitroot(path_abs)
         if normcase(start_drive) != normcase(path_drive):
             raise ValueError("path is on mount %r, start on mount %r" % (
                 path_drive, start_drive))
 
-        start_list = [x for x in start_rest.split(sep) if x]
-        path_list = [x for x in path_rest.split(sep) if x]
+        start_list = start_rest.split(sep) if start_rest else []
+        path_list = path_rest.split(sep) if path_rest else []
         # Work out how much of the filepath is shared by start and path.
         i = 0
         for e1, e2 in zip(start_list, path_list):
@@ -842,7 +843,7 @@ def relpath(path, start=None):
         rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
         if not rel_list:
             return curdir
-        return join(*rel_list)
+        return sep.join(rel_list)
     except (TypeError, ValueError, AttributeError, BytesWarning, 
DeprecationWarning):
         genericpath._check_arg_types('relpath', path, start)
         raise
diff --git a/Lib/posixpath.py b/Lib/posixpath.py
index 56b7915826daf4..f189c3359fbea6 100644
--- a/Lib/posixpath.py
+++ b/Lib/posixpath.py
@@ -532,15 +532,17 @@ def relpath(path, start=None):
         start = os.fspath(start)
 
     try:
-        start_list = [x for x in abspath(start).split(sep) if x]
-        path_list = [x for x in abspath(path).split(sep) if x]
+        start_tail = abspath(start).lstrip(sep)
+        path_tail = abspath(path).lstrip(sep)
+        start_list = start_tail.split(sep) if start_tail else []
+        path_list = path_tail.split(sep) if path_tail else []
         # Work out how much of the filepath is shared by start and path.
         i = len(commonprefix([start_list, path_list]))
 
         rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
         if not rel_list:
             return curdir
-        return join(*rel_list)
+        return sep.join(rel_list)
     except (TypeError, AttributeError, BytesWarning, DeprecationWarning):
         genericpath._check_arg_types('relpath', path, start)
         raise
diff --git a/Misc/NEWS.d/next/Core and 
Builtins/2024-04-07-18-42-09.gh-issue-117607.C978BD.rst b/Misc/NEWS.d/next/Core 
and Builtins/2024-04-07-18-42-09.gh-issue-117607.C978BD.rst
new file mode 100644
index 00000000000000..0c17dfd95ec0ec
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and 
Builtins/2024-04-07-18-42-09.gh-issue-117607.C978BD.rst 
@@ -0,0 +1 @@
+Speedup :func:`os.path.relpath`.

_______________________________________________
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