Skip to content

Commit

Permalink
pythongh-117607: Speedup os.path.relpath() (pythonGH-117608)
Browse files Browse the repository at this point in the history
  • Loading branch information
nineteendo authored and SonicField committed May 8, 2024
1 parent 8d6eeda commit 0d0281c
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 12 deletions.
19 changes: 10 additions & 9 deletions Lib/ntpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'.'
Expand All @@ -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):
Expand All @@ -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
Expand Down
8 changes: 5 additions & 3 deletions Lib/posixpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Speedup :func:`os.path.relpath`.

0 comments on commit 0d0281c

Please sign in to comment.