don't segfault when trying to fdopen() a fd for a dir (closes #22259)

Patch from Brian Kearns.
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index df122f7..3f44aa3 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -194,6 +194,18 @@
         self.fdopen_helper('r')
         self.fdopen_helper('r', 100)
 
+    @unittest.skipUnless(hasattr(posix, 'fdopen'),
+                         'test needs posix.fdopen()')
+    def test_fdopen_directory(self):
+        try:
+            fd = os.open('.', os.O_RDONLY)
+        except OSError as e:
+            self.assertEqual(e.errno, errno.EACCES)
+            self.skipTest("system cannot open directories")
+        with self.assertRaises(IOError) as cm:
+            os.fdopen(fd, 'r')
+        self.assertEqual(cm.exception.errno, errno.EISDIR)
+
     @unittest.skipUnless(hasattr(posix, 'fdopen') and
                          not sys.platform.startswith("sunos"),
                          'test needs posix.fdopen()')
diff --git a/Misc/NEWS b/Misc/NEWS
index 61aab20..2ad993b 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -19,6 +19,9 @@
 Library
 -------
 
+- Issue #22259: Fix segfault when attempting to fopen a file descriptor
+  corresponding to a directory.
+
 - Issue #22236: Fixed Tkinter images copying operations in NoDefaultRoot mode.
 
 - Issue #22191: Fixed warnings.__all__.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index cd4672c..4d0c8fa 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -6861,7 +6861,7 @@
         if (fstat(fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
             PyMem_FREE(mode);
             msg = strerror(EISDIR);
-            exc = PyObject_CallFunction(PyExc_IOError, "(isO)",
+            exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
                                         EISDIR, msg, "<fdopen>");
             if (exc) {
                 PyErr_SetObject(PyExc_IOError, exc);