mirror of
https://github.com/python/cpython.git
synced 2025-09-25 01:43:11 +00:00
gh-117607: Speedup os.path.relpath() (GH-117608)
This commit is contained in:
parent
424438b11e
commit
a7711a2a4e
3 changed files with 16 additions and 12 deletions
|
@ -805,6 +805,9 @@ supports_unicode_filenames = True
|
||||||
def relpath(path, start=None):
|
def relpath(path, start=None):
|
||||||
"""Return a relative version of a path"""
|
"""Return a relative version of a path"""
|
||||||
path = os.fspath(path)
|
path = os.fspath(path)
|
||||||
|
if not path:
|
||||||
|
raise ValueError("no path specified")
|
||||||
|
|
||||||
if isinstance(path, bytes):
|
if isinstance(path, bytes):
|
||||||
sep = b'\\'
|
sep = b'\\'
|
||||||
curdir = b'.'
|
curdir = b'.'
|
||||||
|
@ -816,22 +819,20 @@ def relpath(path, start=None):
|
||||||
|
|
||||||
if start is None:
|
if start is None:
|
||||||
start = curdir
|
start = curdir
|
||||||
|
else:
|
||||||
|
start = os.fspath(start)
|
||||||
|
|
||||||
if not path:
|
|
||||||
raise ValueError("no path specified")
|
|
||||||
|
|
||||||
start = os.fspath(start)
|
|
||||||
try:
|
try:
|
||||||
start_abs = abspath(normpath(start))
|
start_abs = abspath(start)
|
||||||
path_abs = abspath(normpath(path))
|
path_abs = abspath(path)
|
||||||
start_drive, _, start_rest = splitroot(start_abs)
|
start_drive, _, start_rest = splitroot(start_abs)
|
||||||
path_drive, _, path_rest = splitroot(path_abs)
|
path_drive, _, path_rest = splitroot(path_abs)
|
||||||
if normcase(start_drive) != normcase(path_drive):
|
if normcase(start_drive) != normcase(path_drive):
|
||||||
raise ValueError("path is on mount %r, start on mount %r" % (
|
raise ValueError("path is on mount %r, start on mount %r" % (
|
||||||
path_drive, start_drive))
|
path_drive, start_drive))
|
||||||
|
|
||||||
start_list = [x for x in start_rest.split(sep) if x]
|
start_list = start_rest.split(sep) if start_rest else []
|
||||||
path_list = [x for x in path_rest.split(sep) if x]
|
path_list = path_rest.split(sep) if path_rest else []
|
||||||
# Work out how much of the filepath is shared by start and path.
|
# Work out how much of the filepath is shared by start and path.
|
||||||
i = 0
|
i = 0
|
||||||
for e1, e2 in zip(start_list, path_list):
|
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:]
|
rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
|
||||||
if not rel_list:
|
if not rel_list:
|
||||||
return curdir
|
return curdir
|
||||||
return join(*rel_list)
|
return sep.join(rel_list)
|
||||||
except (TypeError, ValueError, AttributeError, BytesWarning, DeprecationWarning):
|
except (TypeError, ValueError, AttributeError, BytesWarning, DeprecationWarning):
|
||||||
genericpath._check_arg_types('relpath', path, start)
|
genericpath._check_arg_types('relpath', path, start)
|
||||||
raise
|
raise
|
||||||
|
|
|
@ -532,15 +532,17 @@ def relpath(path, start=None):
|
||||||
start = os.fspath(start)
|
start = os.fspath(start)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
start_list = [x for x in abspath(start).split(sep) if x]
|
start_tail = abspath(start).lstrip(sep)
|
||||||
path_list = [x for x in abspath(path).split(sep) if x]
|
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.
|
# Work out how much of the filepath is shared by start and path.
|
||||||
i = len(commonprefix([start_list, path_list]))
|
i = len(commonprefix([start_list, path_list]))
|
||||||
|
|
||||||
rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
|
rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
|
||||||
if not rel_list:
|
if not rel_list:
|
||||||
return curdir
|
return curdir
|
||||||
return join(*rel_list)
|
return sep.join(rel_list)
|
||||||
except (TypeError, AttributeError, BytesWarning, DeprecationWarning):
|
except (TypeError, AttributeError, BytesWarning, DeprecationWarning):
|
||||||
genericpath._check_arg_types('relpath', path, start)
|
genericpath._check_arg_types('relpath', path, start)
|
||||||
raise
|
raise
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Speedup :func:`os.path.relpath`.
|
Loading…
Add table
Add a link
Reference in a new issue