]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-86943: implement `pathlib.WindowsPath.is_mount()` (GH-31458)
authorBarney Gale <barney.gale@gmail.com>
Fri, 5 Aug 2022 22:37:44 +0000 (23:37 +0100)
committerGitHub <noreply@github.com>
Fri, 5 Aug 2022 22:37:44 +0000 (15:37 -0700)
Have `pathlib.WindowsPath.is_mount()` call `ntpath.ismount()`. Previously it raised `NotImplementedError` unconditionally.

https://bugs.python.org/issue42777

Doc/library/pathlib.rst
Lib/pathlib.py
Lib/test/test_pathlib.py
Misc/NEWS.d/next/Library/2022-02-21-01-37-00.bpo-42777.nWK3E6.rst [new file with mode: 0644]

index 19944bd7bd0a8912de5a4f53e12abdb3f99be404..f7d7745eef52e7c1bdd198d9fcd1c0d1b46c6290 100644 (file)
@@ -876,10 +876,15 @@ call fails (for example because the path doesn't exist).
    function checks whether *path*'s parent, :file:`path/..`, is on a different
    device than *path*, or whether :file:`path/..` and *path* point to the same
    i-node on the same device --- this should detect mount points for all Unix
-   and POSIX variants.  Not implemented on Windows.
+   and POSIX variants.  On Windows, a mount point is considered to be a drive
+   letter root (e.g. ``c:\``), a UNC share (e.g. ``\\server\share``), or a
+   mounted filesystem directory.
 
    .. versionadded:: 3.7
 
+   .. versionchanged:: 3.12
+      Windows support was added.
+
 
 .. method:: Path.is_symlink()
 
index 2aee71742b23e4d28a7139aeb631a990e7ba899b..54da1c8a625398f69e29d750a5c2cf16a2079d2a 100644 (file)
@@ -1211,23 +1211,9 @@ class Path(PurePath):
 
     def is_mount(self):
         """
-        Check if this path is a POSIX mount point
+        Check if this path is a mount point
         """
-        # Need to exist and be a dir
-        if not self.exists() or not self.is_dir():
-            return False
-
-        try:
-            parent_dev = self.parent.stat().st_dev
-        except OSError:
-            return False
-
-        dev = self.stat().st_dev
-        if dev != parent_dev:
-            return True
-        ino = self.stat().st_ino
-        parent_ino = self.parent.stat().st_ino
-        return ino == parent_ino
+        return self._flavour.pathmod.ismount(self)
 
     def is_symlink(self):
         """
@@ -1378,6 +1364,3 @@ class WindowsPath(Path, PureWindowsPath):
     On a Windows system, instantiating a Path should return this object.
     """
     __slots__ = ()
-
-    def is_mount(self):
-        raise NotImplementedError("Path.is_mount() is unsupported on this system")
index e14b0fca55360faca11327efd7afeb4eb7c1522c..668af8030c0c6a4dbb2ad18c9e8d3d0c91ae3c4d 100644 (file)
@@ -2294,10 +2294,12 @@ class _BasePathTest(object):
         self.assertIs((P / 'fileA\udfff').is_file(), False)
         self.assertIs((P / 'fileA\x00').is_file(), False)
 
-    @only_posix
     def test_is_mount(self):
         P = self.cls(BASE)
-        R = self.cls('/')  # TODO: Work out Windows.
+        if os.name == 'nt':
+            R = self.cls('c:\\')
+        else:
+            R = self.cls('/')
         self.assertFalse((P / 'fileA').is_mount())
         self.assertFalse((P / 'dirA').is_mount())
         self.assertFalse((P / 'non-existing').is_mount())
@@ -2305,8 +2307,7 @@ class _BasePathTest(object):
         self.assertTrue(R.is_mount())
         if os_helper.can_symlink():
             self.assertFalse((P / 'linkA').is_mount())
-        self.assertIs(self.cls('/\udfff').is_mount(), False)
-        self.assertIs(self.cls('/\x00').is_mount(), False)
+        self.assertIs((R / '\udfff').is_mount(), False)
 
     def test_is_symlink(self):
         P = self.cls(BASE)
diff --git a/Misc/NEWS.d/next/Library/2022-02-21-01-37-00.bpo-42777.nWK3E6.rst b/Misc/NEWS.d/next/Library/2022-02-21-01-37-00.bpo-42777.nWK3E6.rst
new file mode 100644 (file)
index 0000000..2491238
--- /dev/null
@@ -0,0 +1 @@
+Implement :meth:`pathlib.Path.is_mount` for Windows paths.