-
-
Notifications
You must be signed in to change notification settings - Fork 31.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-37609: Update ntpath.splitdrive to use native functionality where possible #25261
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,8 +58,31 @@ def normcase(s): | |
# volume), or if a pathname after the volume-letter-and-colon or UNC-resource | ||
# starts with a slash or backslash. | ||
|
||
try: | ||
from nt import _path_splitroot | ||
except ImportError: | ||
_path_splitroot = _splitroot = None | ||
else: | ||
def _splitroot(p): | ||
p = os.fspath(p) | ||
r = _path_splitroot(p) | ||
if isinstance(p, bytes): | ||
return tuple(map(os.fsencode, r)) | ||
return r | ||
Comment on lines
+65
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe change the name to I'm sure you know the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sigh... sorry about that. :-$ |
||
|
||
|
||
def isabs(s): | ||
"""Test whether a path is absolute""" | ||
if _path_splitroot: | ||
try: | ||
root, tail = _path_splitroot(s) | ||
except ValueError: | ||
pass | ||
else: | ||
# UNC roots are always absolute | ||
if root.startswith(sep + sep) or root.startswith(altsep + altsep): | ||
return True | ||
return tail.startswith((sep, altsep)) | ||
s = os.fspath(s) | ||
# Paths beginning with \\?\ are always absolute, but do not | ||
# necessarily contain a drive. | ||
|
@@ -141,17 +164,24 @@ def splitdrive(p): | |
|
||
""" | ||
p = os.fspath(p) | ||
if _splitroot: | ||
try: | ||
return _splitroot(p) | ||
except ValueError: | ||
pass | ||
|
||
if isinstance(p, bytes): | ||
sep = b'\\' | ||
altsep = b'/' | ||
colon = b':' | ||
else: | ||
sep = '\\' | ||
altsep = '/' | ||
colon = ':' | ||
|
||
if len(p) >= 2: | ||
if isinstance(p, bytes): | ||
sep = b'\\' | ||
altsep = b'/' | ||
colon = b':' | ||
else: | ||
sep = '\\' | ||
altsep = '/' | ||
colon = ':' | ||
normp = p.replace(altsep, sep) | ||
if (normp[0:2] == sep*2) and (normp[2:3] != sep): | ||
if (normp[0:2] == sep*2): | ||
# is a UNC path: | ||
# vvvvvvvvvvvvvvvvvvvv drive letter or UNC path | ||
# \\machine\mountpoint\directory\etc\... | ||
|
@@ -160,10 +190,11 @@ def splitdrive(p): | |
if index == -1: | ||
return p[:0], p | ||
index2 = normp.find(sep, index + 1) | ||
# a UNC path can't have two slashes in a row | ||
# (after the initial two) | ||
# a UNC path shouldn't have two slashes in a row | ||
# (after the initial two), but to be consistent with | ||
# the native function, we split before them. | ||
if index2 == index + 1: | ||
return p[:0], p | ||
return p[:index], p[index:] | ||
if index2 == -1: | ||
index2 = len(p) | ||
return p[:index2], p[index2:] | ||
|
@@ -262,19 +293,14 @@ def lexists(path): | |
def ismount(path): | ||
"""Test whether a path is a mount point (a drive root, the root of a | ||
share, or a mounted volume)""" | ||
path = os.fspath(path) | ||
seps = _get_bothseps(path) | ||
path = abspath(path) | ||
path = os.fsdecode(path) | ||
root, rest = splitdrive(path) | ||
if root and root[0] in seps: | ||
return (not rest) or (rest in seps) | ||
if rest in seps: | ||
return True | ||
if root: | ||
return rest in ("/", "\\", "") or root.startswith(("\\\\", "//")) | ||
|
||
if _getvolumepathname: | ||
return path.rstrip(seps) == _getvolumepathname(path).rstrip(seps) | ||
else: | ||
return False | ||
return path.rstrip("/\\") == _getvolumepathname(path).rstrip("/\\") | ||
return False | ||
|
||
|
||
# Expand paths beginning with '~' or '~user'. | ||
|
@@ -505,7 +531,7 @@ def _abspath_fallback(path): | |
""" | ||
|
||
path = os.fspath(path) | ||
if not isabs(path): | ||
if not splitdrive(path)[0]: | ||
if isinstance(path, bytes): | ||
cwd = os.getcwdb() | ||
else: | ||
|
@@ -671,9 +697,9 @@ def realpath(path): | |
return path | ||
|
||
|
||
# Win9x family and earlier have no Unicode filename support. | ||
supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and | ||
sys.getwindowsversion()[3] >= 2) | ||
# All supported platforms have Unicode filenames | ||
supports_unicode_filenames = True | ||
|
||
|
||
def relpath(path, start=None): | ||
"""Return a relative version of a path""" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_path_join('//server/share', 'spam')
should return "//server/share/spam", not "//server/sharespam"_path_join("C:/", "spam")
should return "C:/spam", not "C:spam"_path_join("C:", "")
should return "C:", not "C:\"._path_join("C:", "D:")
should return "D:", not "D:\"I don't like the change to make
_path_splitroot()
shift the separator into the path. It goes against what I expect given the function name, in terms of separating the root from the rest of the path. Theroot
variable here actually has no root path, which is counterintuitive.As it stands, the following fixes the above case by shifting the separator back into
root
. The UNC + relative case has to be handled specially at the end.