summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorTim Golden <mail@timgolden.me.uk>2013-08-01 11:44:00 (GMT)
committerTim Golden <mail@timgolden.me.uk>2013-08-01 11:44:00 (GMT)
commit6b528067c50b9dbf1c53fbc8b6fa959050c5dfcd (patch)
tree523ab53f48183089526e9f3cdd6737fbc7f62027 /Lib
parent536ffe161c014f3646cbf52bc527f2ba9ebd6478 (diff)
downloadcpython-6b528067c50b9dbf1c53fbc8b6fa959050c5dfcd.zip
cpython-6b528067c50b9dbf1c53fbc8b6fa959050c5dfcd.tar.gz
cpython-6b528067c50b9dbf1c53fbc8b6fa959050c5dfcd.tar.bz2
Issue #9035: os.path.ismount now recognises volumes mounted below
a drive root on Windows. Original patch by Atsuo Ishimoto.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/ntpath.py29
-rw-r--r--Lib/test/test_ntpath.py34
2 files changed, 58 insertions, 5 deletions
diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index d81f728..6b65697 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -335,16 +335,35 @@ def lexists(path):
return False
return True
-# Is a path a mount point? Either a root (with or without drive letter)
-# or an UNC path with at most a / or \ after the mount point.
-
+# Is a path a mount point?
+# Any drive letter root (eg c:\)
+# Any share UNC (eg \\server\share)
+# Any volume mounted on a filesystem folder
+#
+# No one method detects all three situations. Historically we've lexically
+# detected drive letter roots and share UNCs. The canonical approach to
+# detecting mounted volumes (querying the reparse tag) fails for the most
+# common case: drive letter roots. The alternative which uses GetVolumePathName
+# fails if the drive letter is the result of a SUBST.
+try:
+ from nt import _getvolumepathname
+except ImportError:
+ _getvolumepathname = None
def ismount(path):
- """Test whether a path is a mount point (defined as root of drive)"""
+ """Test whether a path is a mount point (a drive root, the root of a
+ share, or a mounted volume)"""
seps = _get_bothseps(path)
+ path = abspath(path)
root, rest = splitdrive(path)
if root and root[0] in seps:
return (not rest) or (rest in seps)
- return rest in seps
+ if rest in seps:
+ return True
+
+ if _getvolumepathname:
+ return path.rstrip(seps) == _getvolumepathname(path).rstrip(seps)
+ else:
+ return False
# Expand paths beginning with '~' or '~user'.
diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py
index f809876..66fcf27 100644
--- a/Lib/test/test_ntpath.py
+++ b/Lib/test/test_ntpath.py
@@ -256,6 +256,40 @@ class TestNtpath(unittest.TestCase):
# dialogs (#4804)
ntpath.sameopenfile(-1, -1)
+ def test_ismount(self):
+ self.assertTrue(ntpath.ismount("c:\\"))
+ self.assertTrue(ntpath.ismount("C:\\"))
+ self.assertTrue(ntpath.ismount("c:/"))
+ self.assertTrue(ntpath.ismount("C:/"))
+ self.assertTrue(ntpath.ismount("\\\\.\\c:\\"))
+ self.assertTrue(ntpath.ismount("\\\\.\\C:\\"))
+
+ self.assertTrue(ntpath.ismount(b"c:\\"))
+ self.assertTrue(ntpath.ismount(b"C:\\"))
+ self.assertTrue(ntpath.ismount(b"c:/"))
+ self.assertTrue(ntpath.ismount(b"C:/"))
+ self.assertTrue(ntpath.ismount(b"\\\\.\\c:\\"))
+ self.assertTrue(ntpath.ismount(b"\\\\.\\C:\\"))
+
+ with support.temp_dir() as d:
+ self.assertFalse(ntpath.ismount(d))
+
+ #
+ # Make sure the current folder isn't the root folder
+ # (or any other volume root). The drive-relative
+ # locations below cannot then refer to mount points
+ #
+ drive, path = ntpath.splitdrive(sys.executable)
+ with support.change_cwd(os.path.dirname(sys.executable)):
+ self.assertFalse(ntpath.ismount(drive.lower()))
+ self.assertFalse(ntpath.ismount(drive.upper()))
+
+ self.assertTrue(ntpath.ismount("\\\\localhost\\c$"))
+ self.assertTrue(ntpath.ismount("\\\\localhost\\c$\\"))
+
+ self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$"))
+ self.assertTrue(ntpath.ismount(b"\\\\localhost\\c$\\"))
+
class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
pathmodule = ntpath