Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(192736)

Side by Side Diff: Lib/posixpath.py

Issue 10395: new os.path function to extract common prefix based on path components
Patch Set: Created 6 years, 8 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 """Common operations on Posix pathnames. 1 """Common operations on Posix pathnames.
2 2
3 Instead of importing this module directly, import os and refer to 3 Instead of importing this module directly, import os and refer to
4 this module as os.path. The "os.path" name is an alias for this 4 this module as os.path. The "os.path" name is an alias for this
5 module on Posix systems; on other systems (e.g. Mac, Windows), 5 module on Posix systems; on other systems (e.g. Mac, Windows),
6 os.path provides the same operations in a manner specific to that 6 os.path provides the same operations in a manner specific to that
7 platform, and is an alias to another module (e.g. macpath, ntpath). 7 platform, and is an alias to another module (e.g. macpath, ntpath).
8 8
9 Some of this can actually be useful on non-Posix systems too, e.g. 9 Some of this can actually be useful on non-Posix systems too, e.g.
10 for manipulation of the pathname component of URLs. 10 for manipulation of the pathname component of URLs.
11 """ 11 """
12 12
13 import os 13 import os
14 import sys 14 import sys
15 import stat 15 import stat
16 import genericpath 16 import genericpath
17 from genericpath import * 17 from genericpath import *
18 18
19 __all__ = ["normcase","isabs","join","splitdrive","split","splitext", 19 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
20 "basename","dirname","commonprefix","getsize","getmtime", 20 "basename","dirname","commonprefix","getsize","getmtime",
21 "getatime","getctime","islink","exists","lexists","isdir","isfile", 21 "getatime","getctime","islink","exists","lexists","isdir","isfile",
22 "ismount", "expanduser","expandvars","normpath","abspath", 22 "ismount", "expanduser","expandvars","normpath","abspath",
23 "samefile","sameopenfile","samestat", 23 "samefile","sameopenfile","samestat",
24 "curdir","pardir","sep","pathsep","defpath","altsep","extsep", 24 "curdir","pardir","sep","pathsep","defpath","altsep","extsep",
25 "devnull","realpath","supports_unicode_filenames","relpath"] 25 "devnull","realpath","supports_unicode_filenames","relpath",
26 "commonpath"]
26 27
27 # Strings representing various path-related bits and pieces. 28 # Strings representing various path-related bits and pieces.
28 # These are primarily for export; internally, they are hardcoded. 29 # These are primarily for export; internally, they are hardcoded.
29 curdir = '.' 30 curdir = '.'
30 pardir = '..' 31 pardir = '..'
31 extsep = '.' 32 extsep = '.'
32 sep = '/' 33 sep = '/'
33 pathsep = ':' 34 pathsep = ':'
34 defpath = ':/bin:/usr/bin' 35 defpath = ':/bin:/usr/bin'
35 altsep = None 36 altsep = None
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 start_list = [x for x in abspath(start).split(sep) if x] 461 start_list = [x for x in abspath(start).split(sep) if x]
461 path_list = [x for x in abspath(path).split(sep) if x] 462 path_list = [x for x in abspath(path).split(sep) if x]
462 463
463 # Work out how much of the filepath is shared by start and path. 464 # Work out how much of the filepath is shared by start and path.
464 i = len(commonprefix([start_list, path_list])) 465 i = len(commonprefix([start_list, path_list]))
465 466
466 rel_list = [pardir] * (len(start_list)-i) + path_list[i:] 467 rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
467 if not rel_list: 468 if not rel_list:
468 return curdir 469 return curdir
469 return join(*rel_list) 470 return join(*rel_list)
471
472
473 def commonpath(paths):
474 """Given a sequence of path names, returns the longest common sub-path."""
475
476 if not paths:
477 return None
478
479 if any(isabs(p) for p in paths) and any(not isabs(p) for p in paths):
480 # There is a mix of absolute and relative pathnames.
481 return None
482
483 sep = _get_sep(paths[0])
484 prefix = sep if isabs(paths[0]) else ''
485
486 try:
487 split_paths = [path.split(sep) for path in paths]
488 except TypeError:
489 valid_types = all(isinstance(p, (str, bytes, bytearray))
490 for p in paths)
491 if valid_types:
492 # Must have a mixture of text and binary data
493 raise TypeError("Can't mix strings and bytes in path "
494 "components.") from None
495 raise
496
497 s1 = min(split_paths)
498 s2 = max(split_paths)
499 common = s1
500 for i, c in enumerate(s1):
501 if c != s2[i]:
502 common = s1[:i]
503 break
504
505 if not common:
506 return prefix
507 else:
508 return prefix + join(*common).rstrip(sep)
storchaka 2012/11/06 15:45:05 Why not sep.join(*common)?
rafik 2012/11/13 01:17:12 Using rstrip is the easiest way I found for enforc
storchaka 2012/11/13 10:30:51 join(*'/usr//lib'.split('/')) gives 'usr/lib', '/'
OLDNEW

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+