mirror of https://github.com/python/cpython.git
Patch 1339796: add a relpath() function to os.path.
This commit is contained in:
parent
6de691d78c
commit
6f187743ff
|
@ -189,6 +189,15 @@ operating system).
|
||||||
\versionadded{2.2}
|
\versionadded{2.2}
|
||||||
\end{funcdesc}
|
\end{funcdesc}
|
||||||
|
|
||||||
|
\begin{funcdesc}{relpath}{path\optional{, start}}
|
||||||
|
Return a relative filepath to \var{path} either from the current
|
||||||
|
directory or from an optional \var{start} point.
|
||||||
|
|
||||||
|
\var{start} defaults to \member{os.curdir}.
|
||||||
|
Availability: Windows, \UNIX.
|
||||||
|
\versionadded{2.6}
|
||||||
|
\end{funcdesc}
|
||||||
|
|
||||||
\begin{funcdesc}{samefile}{path1, path2}
|
\begin{funcdesc}{samefile}{path1, path2}
|
||||||
Return \code{True} if both pathname arguments refer to the same file or
|
Return \code{True} if both pathname arguments refer to the same file or
|
||||||
directory (as indicated by device number and i-node number).
|
directory (as indicated by device number and i-node number).
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
"getatime","getctime", "islink","exists","lexists","isdir","isfile",
|
"getatime","getctime", "islink","exists","lexists","isdir","isfile",
|
||||||
"ismount","walk","expanduser","expandvars","normpath","abspath",
|
"ismount","walk","expanduser","expandvars","normpath","abspath",
|
||||||
"splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
|
"splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
|
||||||
"extsep","devnull","realpath","supports_unicode_filenames"]
|
"extsep","devnull","realpath","supports_unicode_filenames","relpath"]
|
||||||
|
|
||||||
# strings representing various path-related bits and pieces
|
# strings representing various path-related bits and pieces
|
||||||
curdir = '.'
|
curdir = '.'
|
||||||
|
@ -465,3 +465,29 @@ def abspath(path):
|
||||||
# Win9x family and earlier have no Unicode filename support.
|
# Win9x family and earlier have no Unicode filename support.
|
||||||
supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
|
supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
|
||||||
sys.getwindowsversion()[3] >= 2)
|
sys.getwindowsversion()[3] >= 2)
|
||||||
|
|
||||||
|
def relpath(path, start=curdir):
|
||||||
|
"""Return a relative version of a path"""
|
||||||
|
|
||||||
|
if not path:
|
||||||
|
raise ValueError("no path specified")
|
||||||
|
start_list = abspath(start).split(sep)
|
||||||
|
path_list = abspath(path).split(sep)
|
||||||
|
if start_list[0].lower() != path_list[0].lower():
|
||||||
|
unc_path, rest = splitunc(path)
|
||||||
|
unc_start, rest = splitunc(start)
|
||||||
|
if bool(unc_path) ^ bool(unc_start):
|
||||||
|
raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
|
||||||
|
% (path, start))
|
||||||
|
else:
|
||||||
|
raise ValueError("path is on drive %s, start on drive %s"
|
||||||
|
% (path_list[0], start_list[0]))
|
||||||
|
# Work out how much of the filepath is shared by start and path.
|
||||||
|
for i in range(min(len(start_list), len(path_list))):
|
||||||
|
if start_list[i].lower() != path_list[i].lower():
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
|
||||||
|
return join(*rel_list)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
"ismount","walk","expanduser","expandvars","normpath","abspath",
|
"ismount","walk","expanduser","expandvars","normpath","abspath",
|
||||||
"samefile","sameopenfile","samestat",
|
"samefile","sameopenfile","samestat",
|
||||||
"curdir","pardir","sep","pathsep","defpath","altsep","extsep",
|
"curdir","pardir","sep","pathsep","defpath","altsep","extsep",
|
||||||
"devnull","realpath","supports_unicode_filenames"]
|
"devnull","realpath","supports_unicode_filenames","relpath"]
|
||||||
|
|
||||||
# strings representing various path-related bits and pieces
|
# strings representing various path-related bits and pieces
|
||||||
curdir = '.'
|
curdir = '.'
|
||||||
|
@ -382,3 +382,18 @@ def _resolve_link(path):
|
||||||
return path
|
return path
|
||||||
|
|
||||||
supports_unicode_filenames = False
|
supports_unicode_filenames = False
|
||||||
|
|
||||||
|
def relpath(path, start=curdir):
|
||||||
|
"""Return a relative version of a path"""
|
||||||
|
|
||||||
|
if not path:
|
||||||
|
raise ValueError("no path specified")
|
||||||
|
|
||||||
|
start_list = abspath(start).split(sep)
|
||||||
|
path_list = abspath(path).split(sep)
|
||||||
|
|
||||||
|
# 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:]
|
||||||
|
return join(*rel_list)
|
||||||
|
|
|
@ -157,6 +157,16 @@ def tester(fn, wantResult):
|
||||||
else:
|
else:
|
||||||
tester('ntpath.abspath("C:\\")', "C:\\")
|
tester('ntpath.abspath("C:\\")', "C:\\")
|
||||||
|
|
||||||
|
currentdir = os.path.split(os.getcwd())[-1]
|
||||||
|
tester('ntpath.relpath("a")', 'a')
|
||||||
|
tester('ntpath.relpath(os.path.abspath("a"))', 'a')
|
||||||
|
tester('ntpath.relpath("a/b")', 'a\\b')
|
||||||
|
tester('ntpath.relpath("../a/b")', '..\\a\\b')
|
||||||
|
tester('ntpath.relpath("a", "../b")', '..\\'+currentdir+'\\a')
|
||||||
|
tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b')
|
||||||
|
tester('ntpath.relpath("a", "b/c")', '..\\..\\a')
|
||||||
|
tester('ntpath.relpath("//conky/mountpoint/a", "//conky/mountpoint/b/c")', '..\\..\\a')
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
raise TestFailed(str(errors) + " errors.")
|
raise TestFailed(str(errors) + " errors.")
|
||||||
elif verbose:
|
elif verbose:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
from test import test_support
|
from test import test_support
|
||||||
|
|
||||||
import posixpath, os
|
import posixpath, os
|
||||||
from posixpath import realpath, abspath, join, dirname, basename
|
from posixpath import realpath, abspath, join, dirname, basename, relpath
|
||||||
|
|
||||||
# An absolute path to a temporary filename for testing. We can't rely on TESTFN
|
# An absolute path to a temporary filename for testing. We can't rely on TESTFN
|
||||||
# being an absolute path, so we need this.
|
# being an absolute path, so we need this.
|
||||||
|
@ -479,6 +479,17 @@ def test_realpath_resolve_first(self):
|
||||||
safe_rmdir(ABSTFN + "/k")
|
safe_rmdir(ABSTFN + "/k")
|
||||||
safe_rmdir(ABSTFN)
|
safe_rmdir(ABSTFN)
|
||||||
|
|
||||||
|
def test_relpath(self):
|
||||||
|
currentdir = os.path.split(os.getcwd())[-1]
|
||||||
|
self.assertRaises(ValueError, posixpath.relpath, "")
|
||||||
|
self.assertEqual(posixpath.relpath("a"), "a")
|
||||||
|
self.assertEqual(posixpath.relpath(os.path.abspath("a")), "a")
|
||||||
|
self.assertEqual(posixpath.relpath("a/b"), "a/b")
|
||||||
|
self.assertEqual(posixpath.relpath("../a/b"), "../a/b")
|
||||||
|
self.assertEqual(posixpath.relpath("a", "../b"), "../"+currentdir+"/a")
|
||||||
|
self.assertEqual(posixpath.relpath("a/b", "../c"), "../"+currentdir+"/a/b")
|
||||||
|
self.assertEqual(posixpath.relpath("a", "b/c"), "../../a")
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test_support.run_unittest(PosixPathTest)
|
test_support.run_unittest(PosixPathTest)
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ Luigi Ballabio
|
||||||
Michael J. Barber
|
Michael J. Barber
|
||||||
Chris Barker
|
Chris Barker
|
||||||
Quentin Barnes
|
Quentin Barnes
|
||||||
|
Richard Barran
|
||||||
Cesar Eduardo Barros
|
Cesar Eduardo Barros
|
||||||
Des Barry
|
Des Barry
|
||||||
Ulf Bartelt
|
Ulf Bartelt
|
||||||
|
|
|
@ -191,6 +191,8 @@ Library
|
||||||
of those present. Also, it tries the Windows default browser before
|
of those present. Also, it tries the Windows default browser before
|
||||||
trying Mozilla variants.
|
trying Mozilla variants.
|
||||||
|
|
||||||
|
- Patch #1339796: add a relpath() function to os.path.
|
||||||
|
|
||||||
- Patch #1681153: the wave module now closes a file object it opened if
|
- Patch #1681153: the wave module now closes a file object it opened if
|
||||||
initialization failed.
|
initialization failed.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue