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

Side by Side Diff: Lib/ntpath.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 # Module 'ntpath' -- common operations on WinNT/Win95 pathnames 1 # Module 'ntpath' -- common operations on WinNT/Win95 pathnames
2 """Common pathname manipulations, WindowsNT/95 version. 2 """Common pathname manipulations, WindowsNT/95 version.
3 3
4 Instead of importing this module directly, import os and refer to this 4 Instead of importing this module directly, import os and refer to this
5 module as os.path. 5 module as os.path.
6 """ 6 """
7 7
8 import os 8 import os
9 import sys 9 import sys
10 import stat 10 import stat
11 import genericpath 11 import genericpath
12 from genericpath import * 12 from genericpath import *
13 13
14 __all__ = ["normcase","isabs","join","splitdrive","split","splitext", 14 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
15 "basename","dirname","commonprefix","getsize","getmtime", 15 "basename","dirname","commonprefix","getsize","getmtime",
16 "getatime","getctime", "islink","exists","lexists","isdir","isfile", 16 "getatime","getctime", "islink","exists","lexists","isdir","isfile",
17 "ismount", "expanduser","expandvars","normpath","abspath", 17 "ismount", "expanduser","expandvars","normpath","abspath",
18 "splitunc","curdir","pardir","sep","pathsep","defpath","altsep", 18 "splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
19 "extsep","devnull","realpath","supports_unicode_filenames","relpath", 19 "extsep","devnull","realpath","supports_unicode_filenames","relpath",
20 "samefile", "sameopenfile",] 20 "samefile", "sameopenfile", 'commonpath']
21 21
22 # strings representing various path-related bits and pieces 22 # strings representing various path-related bits and pieces
23 # These are primarily for export; internally, they are hardcoded. 23 # These are primarily for export; internally, they are hardcoded.
24 curdir = '.' 24 curdir = '.'
25 pardir = '..' 25 pardir = '..'
26 extsep = '.' 26 extsep = '.'
27 sep = '\\' 27 sep = '\\'
28 pathsep = ';' 28 pathsep = ';'
29 altsep = '/' 29 altsep = '/'
30 defpath = '.;C:\\bin' 30 defpath = '.;C:\\bin'
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 i += 1 627 i += 1
628 628
629 if isinstance(path, bytes): 629 if isinstance(path, bytes):
630 pardir = b'..' 630 pardir = b'..'
631 else: 631 else:
632 pardir = '..' 632 pardir = '..'
633 rel_list = [pardir] * (len(start_list)-i) + path_list[i:] 633 rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
634 if not rel_list: 634 if not rel_list:
635 return _get_dot(path) 635 return _get_dot(path)
636 return join(*rel_list) 636 return join(*rel_list)
637
638
639 def commonpath(paths):
640 """Given a sequence of path names, returns the longest common sub-path."""
641
642 if not paths:
643 return None
644
645 if any(isabs(p) for p in paths) and any(not isabs(p) for p in paths):
646 # There is a mix of absolute and relative pathnames.
647 return None
648
649 drivespecs = [splitdrive(p)[0] for p in paths]
storchaka 2012/11/06 15:45:05 splitdrive() is an expensive function, it will be
650 pathspecs = [splitdrive(normcase(p))[1] for p in paths]
eric.araujo 2012/11/06 16:20:32 I thought calling normcase or normpath was the res
storchaka 2012/11/06 16:54:49 May be normpath(), but not normcase(). In any cas
651
652 # Check that all drive letters or UNC paths match.
653 drive_or_unc = drivespecs[0]
storchaka 2012/11/06 15:45:05 drive_or_unc looks too long.
654 try:
655 if not all(d == drive_or_unc for d in drivespecs):
656 return None
657 except TypeError:
658 valid_types = all(isinstance(p, (str, bytes, bytearray))
659 for p in paths)
660 if valid_types:
661 # Must have a mixture of text and binary data.
662 raise TypeError("Can't mix strings and bytes in path "
663 "components.") from None
664 raise
665
666
storchaka 2012/11/06 15:45:05 Double emplyline inside a function is not good.
667 sep = _get_sep(pathspecs[0])
668 split_paths = [path.split(sep) for path in pathspecs]
669 s1 = min(split_paths)
670 s2 = max(split_paths)
671 common = s1
672 for i, c in enumerate(s1):
673 if c != s2[i]:
674 common = s1[:i]
storchaka 2012/11/06 15:45:05 It will be better to preserve characters case. com
675 break
676
677 if not common:
678 return drive_or_unc
679 else:
680 return drive_or_unc + join(*common).rstrip(sep)
storchaka 2012/11/06 15:45:05 As in posixpath here should be a prefix (sep or ''
637 681
638 682
639 # determine if two files are in fact the same file 683 # determine if two files are in fact the same file
640 try: 684 try:
641 # GetFinalPathNameByHandle is available starting with Windows 6.0. 685 # GetFinalPathNameByHandle is available starting with Windows 6.0.
642 # Windows XP and non-Windows OS'es will mock _getfinalpathname. 686 # Windows XP and non-Windows OS'es will mock _getfinalpathname.
643 if sys.getwindowsversion()[:2] >= (6, 0): 687 if sys.getwindowsversion()[:2] >= (6, 0):
644 from nt import _getfinalpathname 688 from nt import _getfinalpathname
645 else: 689 else:
646 raise ImportError 690 raise ImportError
(...skipping 25 matching lines...) Expand all
672 716
673 try: 717 try:
674 # The genericpath.isdir implementation uses os.stat and checks the mode 718 # The genericpath.isdir implementation uses os.stat and checks the mode
675 # attribute to tell whether or not the path is a directory. 719 # attribute to tell whether or not the path is a directory.
676 # This is overkill on Windows - just pass the path to GetFileAttributes 720 # This is overkill on Windows - just pass the path to GetFileAttributes
677 # and check the attribute from there. 721 # and check the attribute from there.
678 from nt import _isdir as isdir 722 from nt import _isdir as isdir
679 except ImportError: 723 except ImportError:
680 # Use genericpath.isdir as imported above. 724 # Use genericpath.isdir as imported above.
681 pass 725 pass
OLDNEW

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