mirror of
https://github.com/python/cpython.git
synced 2025-11-25 04:34:37 +00:00
Issue #10395: Added os.path.commonpath(). Implemented in posixpath and ntpath.
Based on patch by Rafik Draoui.
This commit is contained in:
parent
dd83bd2f9c
commit
3822093143
7 changed files with 255 additions and 5 deletions
|
|
@ -22,7 +22,8 @@ __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
|
|||
"ismount", "expanduser","expandvars","normpath","abspath",
|
||||
"samefile","sameopenfile","samestat",
|
||||
"curdir","pardir","sep","pathsep","defpath","altsep","extsep",
|
||||
"devnull","realpath","supports_unicode_filenames","relpath"]
|
||||
"devnull","realpath","supports_unicode_filenames","relpath",
|
||||
"commonpath"]
|
||||
|
||||
# Strings representing various path-related bits and pieces.
|
||||
# These are primarily for export; internally, they are hardcoded.
|
||||
|
|
@ -455,3 +456,45 @@ def relpath(path, start=None):
|
|||
except (TypeError, AttributeError, BytesWarning, DeprecationWarning):
|
||||
genericpath._check_arg_types('relpath', path, start)
|
||||
raise
|
||||
|
||||
|
||||
# Return the longest common sub-path of the sequence of paths given as input.
|
||||
# The paths are not normalized before comparing them (this is the
|
||||
# responsibility of the caller). Any trailing separator is stripped from the
|
||||
# returned path.
|
||||
|
||||
def commonpath(paths):
|
||||
"""Given a sequence of path names, returns the longest common sub-path."""
|
||||
|
||||
if not paths:
|
||||
raise ValueError('commonpath() arg is an empty sequence')
|
||||
|
||||
if isinstance(paths[0], bytes):
|
||||
sep = b'/'
|
||||
curdir = b'.'
|
||||
else:
|
||||
sep = '/'
|
||||
curdir = '.'
|
||||
|
||||
try:
|
||||
split_paths = [path.split(sep) for path in paths]
|
||||
|
||||
try:
|
||||
isabs, = set(p[:1] == sep for p in paths)
|
||||
except ValueError:
|
||||
raise ValueError("Can't mix absolute and relative paths") from None
|
||||
|
||||
split_paths = [[c for c in s if c and c != curdir] for s in split_paths]
|
||||
s1 = min(split_paths)
|
||||
s2 = max(split_paths)
|
||||
common = s1
|
||||
for i, c in enumerate(s1):
|
||||
if c != s2[i]:
|
||||
common = s1[:i]
|
||||
break
|
||||
|
||||
prefix = sep if isabs else sep[:0]
|
||||
return prefix + sep.join(common)
|
||||
except (TypeError, AttributeError):
|
||||
genericpath._check_arg_types('commonpath', *paths)
|
||||
raise
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue