diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index bb9a7c86464050..53e7a4c1921d17 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -299,8 +299,8 @@ the :mod:`glob` module.) i-node on the same device --- this should detect mount points for all Unix and POSIX variants. It is not able to reliably detect bind mounts on the same filesystem. On Linux systems, it will always return ``True`` for btrfs - subvolumes, even if they aren't mount points. On Windows, a drive letter root - and a share UNC are always mount points, and for any other path + subvolumes, even if they aren't mount points. On Windows, a existent drive + letter root and a share UNC are always mount points, and for any other path ``GetVolumePathName`` is called to see if it is different from the input path. .. versionchanged:: 3.4 diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 08c529c5963a4d..1d9ee2b70d95b4 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -285,14 +285,19 @@ def ismount(path): path = abspath(path) drive, root, rest = splitroot(path) if drive and drive[0] in seps: + # Share path is a mount point if it conforms to UNC. return not rest if root and not rest: - return True - + # Drive root is a mount point if it exists. + return exists(path) if _getvolumepathname: - x = path.rstrip(seps) - y =_getvolumepathname(path).rstrip(seps) - return x.casefold() == y.casefold() + try: + # The path is a mount point if it's a mounted volume. + x = path.rstrip(seps) + y = _getvolumepathname(path).rstrip(seps) + return x.casefold() == y.casefold() + except (OSError, FileNotFoundError): + return False else: return False diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index b9cd75a3b8adea..52736d1d1c85f4 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -1354,19 +1354,31 @@ def test_sameopenfile(self): 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:\\")) + if sys.platform == "win32": + 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:\\")) + + # Look for a non-existent drive letter that can be used to test + # behaviour of ismount(). + for drive in "DEFGHIJKLMNOPQRSTUVWXYZ": + if not ntpath.exists(drive + ":\\"): + self.assertFalse(ntpath.ismount(drive + ":\\")) + self.assertFalse(ntpath.ismount(drive + ":\\NotExist")) + break + else: + if support.verbose: + print("No missing drive found to test 'ismount'") with os_helper.temp_dir() as d: self.assertFalse(ntpath.ismount(d)) diff --git a/Misc/ACKS b/Misc/ACKS index 0812b229e0ada4..c56800990a68b8 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -498,6 +498,7 @@ Eugene Dvurechenski Karmen Dykstra Josip Dzolonga Maxim Dzumanenko +Thomas Earp Hans Eckardt Rodolpho Eckhardt Ulrich Eckhardt diff --git a/Misc/NEWS.d/next/Library/2025-10-10-16-13-00.gh-issue-73045.4ks8g7.rst b/Misc/NEWS.d/next/Library/2025-10-10-16-13-00.gh-issue-73045.4ks8g7.rst new file mode 100644 index 00000000000000..35b29fbc3389ac --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-10-16-13-00.gh-issue-73045.4ks8g7.rst @@ -0,0 +1 @@ +For Windows, os.path.ismount() now returns False for non-existent drive letter roots.