diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 3cfe08a1fe1f7a..bbaa59b657e898 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -302,8 +302,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 7d637325240f1c..2dcf34183db880 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 3a3c60dea1345f..66a8be9cc5771b 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -1367,19 +1367,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 feb16a62792e7f..f8a3c745f0bda8 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -500,6 +500,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.