8000 gh-117114: Add `isdevdrive` to `posixpath` by nineteendo · Pull Request #117115 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-117114: Add isdevdrive to posixpath #117115

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

Merged
merged 11 commits into from
Mar 25, 2024
Prev Previous commit
Next Next commit
Make requested changes
  • Loading branch information
nineteendo committed Mar 22, 2024
commit d4aef8676f28bdcf0f2b91ec3b2813258a8bcc33
60 changes: 31 additions & 29 deletions Lib/ntpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,22 @@ def splitdrive(p):
Paths cannot contain both a drive letter and a UNC path.

"""
drive, root, tail = splitroot(p)
return drive, root + tail


def splitroot(p):
"""Split a pathname into drive, root and tail. The drive is defined
exactly as in splitdrive(). On Windows, the root may be a single path
separator or an empty string. The tail contains anything after the root.
For example:

splitroot('//server/share/') == ('//server/share', '/', '')
splitroot('C:/Users/Barney') == ('C:', '/', 'Users/Barney')
splitroot('C:///spam///ham') == ('C:', '/', '//spam///ham')
splitroot('Windows/notepad') == ('', '', 'Windows/notepad')
"""
# Split drive
p = os.fspath(p)
if isinstance(p, bytes):
sep = b'\\'
Expand All @@ -180,41 +196,27 @@ def splitdrive(p):
if normp[:1] != sep:
if normp[1:2] == colon:
# Drive-letter drives, e.g. X:
return p[:2], p[2:]
elif normp[1:2] == sep:
drive, p = p[:2], p[2:]
else:
drive = p[:0]
elif normp[1:2] != sep:
drive = p[:0]
else:
# UNC drives, e.g. \\server\share or \\?\UNC\server\share
# Device drives, e.g. \\.\device or \\?\device
start = 8 if normp[:8].upper() == unc_prefix else 2
index = normp.find(sep, start)
if index == -1:
return p, p[:0]
index2 = normp.find(sep, index + 1)
if index2 == -1:
return p, p[:0]
return p[:index2], p[index2:]
return p[:0], p


def splitroot(p):
"""Split a pathname into drive, root and tail. The drive is defined
exactly as in splitdrive(). On Windows, the root may be a single path
separator or an empty string. The tail contains anything after the root.
For example:
drive, p = p, p[:0]
else:
index2 = normp.find(sep, index + 1)
if index2 == -1:
drive, p = p, p[:0]
else:
drive, p = p[:index2], p[index2:]

splitroot('//server/share/') == ('//server/share', '/', '')
splitroot('C:/Users/Barney') == ('C:', '/', 'Users/Barney')
splitroot('C:///spam///ham') == ('C:', '/', '//spam///ham')
splitroot('Windows/notepad') == ('', '', 'Windows/notepad')
"""
drive, p = splitdrive(p)
if isinstance(p, bytes):
sep = b'\\'
altsep = b'/'
else:
sep = '\\'
altsep = '/'
normp = p.replace(altsep, sep)
if normp[:1] == sep:
# Split root
if normp[len(drive):len(drive)+1] == sep:
# Absolute path, e.g. X:\Windows
return drive, p[:1], p[1:]
# Relative path, e.g. X:Windows
Expand Down
21 changes: 12 additions & 9 deletions Lib/posixpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"samefile","sameopenfile","samestat",
"curdir","pardir","sep","pathsep","defpath","altsep","extsep",
"devnull","realpath","supports_unicode_filenames","relpath",
"commonpath", "isjunction","isreserved","isdevdrive"]
"commonpath", "isjunction","isdevdrive"]


def _get_sep(path):
Expand Down Expand Up @@ -168,14 +168,23 @@ def splitroot(p):

def basename(p):
"""Returns the final component of a pathname"""
return split(p)[1]
p = os.fspath(p)
sep = _get_sep(p)
i = p.rfind(sep) + 1
return p[i:]


# Return the head (dirname) part of a path, same as split(path)[0].

def dirname(p):
"""Returns the directory component of a pathname"""
return split(p)[0]
p = os.fspath(p)
sep = _get_sep(p)
i = p.rfind(sep) + 1
head = p[:i]
if head and head != sep*len(head):
head = head.rstrip(sep)
return head


# Is a path a junction?
Expand All @@ -187,12 +196,6 @@ def isjunction(path):
return False


def isreserved(path):
"""Return true if the pathname is reserved by the system.
Always returns False on posix"""
return False


def isdevdrive(path):
"""Determines whether the specified path is on a Dev Drive.
Dev Drives are not a part of posix semantics"""
Expand Down
9 changes: 4 additions & 5 deletions Lib/test/test_ntpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,6 @@ def test_splitdrive(self):
tester('ntpath.splitdrive("//?/UNC/server/share/dir")',
("//?/UNC/server/share", "/dir"))

# gh-101363: match GetFullPathNameW() drive letter parsing behaviour
tester('ntpath.splitdrive(" :/foo")', (" :", "/foo"))
tester('ntpath.splitdrive("/:/foo")', ("", "/:/foo"))


def test_splitroot(self):
tester("ntpath.splitroot('')", ('', '', ''))
tester("ntpath.splitroot('foo')", ('', '', 'foo'))
Expand Down Expand Up @@ -215,6 +210,10 @@ def test_splitroot(self):
tester('ntpath.splitroot("//x")', ("//x", "", "")) # non-empty server & missing share
tester('ntpath.splitroot("//x/")', ("//x/", "", "")) # non-empty server & empty share

# gh-101363: match GetFullPathNameW() drive letter parsing behaviour
tester('ntpath.splitroot(" :/foo")', (" :", "/", "foo"))
tester('ntpath.splitroot("/:/foo")', ("", "/", ":/foo"))

def test_split(self):
tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar'))
tester('ntpath.split("\\\\conky\\mountpoint\\foo\\bar")',
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Added posix implementation for isreserved & isdevdrive.
Added posix implementation for isdevdrive.
0