Commits

Antoine Pitrou  committed c62ac19

Add is_sock, is_fifo, is_char_device, is_block_device

  • Participants
  • Parent commits 5fd3dd1
  • Branches pep428

Comments (0)

Files changed (3)

File docs/index.rst

    as permission errors) are propagated.
 
 
+.. method:: Path.is_sock()
+
+   Return True if the path points to a Unix socket (or a symbolic link
+   pointing to a Unix socket), False if it points to another kind of file.
+
+   False is also returned if the path doesn't exist or is a broken symlink;
+   other errors (such as permission errors) are propagated.
+
+
+.. method:: Path.is_fifo()
+
+   Return True if the path points to a FIFO (or a symbolic link
+   pointing to a FIFO), False if it points to another kind of file.
+
+   False is also returned if the path doesn't exist or is a broken symlink;
+   other errors (such as permission errors) are propagated.
+
+
+.. method:: Path.is_block_device()
+
+   Return True if the path points to a block device (or a symbolic link
+   pointing to a block device), False if it points to another kind of file.
+
+   False is also returned if the path doesn't exist or is a broken symlink;
+   other errors (such as permission errors) are propagated.
+
+
+.. method:: Path.is_char_device()
+
+   Return True if the path points to a character device (or a symbolic link
+   pointing to a character device), False if it points to another kind of file.
+
+   False is also returned if the path doesn't exist or is a broken symlink;
+   other errors (such as permission errors) are propagated.
+
+
 .. method:: Path.iterdir()
 
    When the path points to a directory, yield path objects of the directory
 from errno import EINVAL, ENOENT, EEXIST
 from itertools import chain, count
 from operator import attrgetter
-from stat import S_ISDIR, S_ISLNK, S_ISREG
+from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO
 try:
     from urllib import quote as urlquote, quote as urlquote_from_bytes
 except ImportError:
         Whether this path is a symbolic link.
         """
         try:
-            st = self.lstat()
+            return S_ISLNK(self.lstat().st_mode)
         except OSError as e:
             if e.errno != ENOENT:
                 raise
             # Path doesn't exist
             return False
-        return S_ISLNK(st.st_mode)
+
+    def is_block_device(self):
+        """
+        Whether this path is a block device.
+        """
+        try:
+            return S_ISBLK(self.stat().st_mode)
+        except OSError as e:
+            if e.errno != ENOENT:
+                raise
+            # Path doesn't exist or is a broken symlink
+            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+            return False
+
+    def is_char_device(self):
+        """
+        Whether this path is a character device.
+        """
+        try:
+            return S_ISCHR(self.stat().st_mode)
+        except OSError as e:
+            if e.errno != ENOENT:
+                raise
+            # Path doesn't exist or is a broken symlink
+            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+            return False
+
+    def is_fifo(self):
+        """
+        Whether this path is a FIFO.
+        """
+        try:
+            return S_ISFIFO(self.stat().st_mode)
+        except OSError as e:
+            if e.errno != ENOENT:
+                raise
+            # Path doesn't exist or is a broken symlink
+            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+            return False
+
+    def is_sock(self):
+        """
+        Whether this path is a socket.
+        """
+        try:
+            return S_ISSOCK(self.stat().st_mode)
+        except OSError as e:
+            if e.errno != ENOENT:
+                raise
+            # Path doesn't exist or is a broken symlink
+            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+            return False
 
 
 class PosixPath(Path, PurePosixPath):

File test_pathlib.py

 import pathlib
 import pickle
 import shutil
+import socket
 import stat
 import sys
 import tempfile
             self.assertTrue((P / 'linkB').is_symlink())
             self.assertTrue((P/ 'brokenLink').is_symlink())
 
+    def test_is_fifo_false(self):
+        P = self.cls(BASE)
+        self.assertFalse((P / 'fileA').is_fifo())
+        self.assertFalse((P / 'dirA').is_fifo())
+        self.assertFalse((P / 'non-existing').is_fifo())
+
+    @unittest.skipUnless(hasattr(os, "mkfifo"), "os.mkfifo() required")
+    def test_is_fifo_true(self):
+        P = self.cls(BASE, 'myfifo')
+        os.mkfifo(str(P))
+        self.assertTrue(P.is_fifo())
+        self.assertFalse(P.is_sock())
+        self.assertFalse(P.is_file())
+
+    def test_is_sock_false(self):
+        P = self.cls(BASE)
+        self.assertFalse((P / 'fileA').is_sock())
+        self.assertFalse((P / 'dirA').is_sock())
+        self.assertFalse((P / 'non-existing').is_sock())
+
+    @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
+    def test_is_sock_true(self):
+        P = self.cls(BASE, 'mysock')
+        sock = socket.socket(socket.SOCK_STREAM, socket.AF_UNIX)
+        self.addCleanup(sock.close)
+        sock.bind(str(P))
+        self.assertTrue(P.is_sock())
+        self.assertFalse(P.is_fifo())
+        self.assertFalse(P.is_file())
+
+    def test_is_block_device_false(self):
+        P = self.cls(BASE)
+        self.assertFalse((P / 'fileA').is_block_device())
+        self.assertFalse((P / 'dirA').is_block_device())
+        self.assertFalse((P / 'non-existing').is_block_device())
+
+    def test_is_char_device_false(self):
+        P = self.cls(BASE)
+        self.assertFalse((P / 'fileA').is_char_device())
+        self.assertFalse((P / 'dirA').is_char_device())
+        self.assertFalse((P / 'non-existing').is_char_device())
+
+    def test_is_char_device_true(self):
+        # Under Unix, /dev/null should generally be a char device
+        P = self.cls('/dev/null')
+        if not P.exists():
+            self.skipTest("/dev/null required")
+        self.assertTrue(P.is_char_device())
+        self.assertFalse(P.is_block_device())
+        self.assertFalse(P.is_file())
+
     def test_pickling_common(self):
         p = self.cls(BASE, 'fileA')
         for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):