Skip to content

Commit feecbf7

Browse files
committed
feat: add test coversage for PyFile_FromFd
1 parent 805e336 commit feecbf7

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

Lib/test/test_capi/test_file.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import io
22
import os
3+
import errno
34
import unittest
45
from test import support
56
from test.support import import_helper, os_helper, warnings_helper
@@ -33,6 +34,30 @@ def test_pyfile_fromfd(self):
3334
finally:
3435
obj.close()
3536

37+
# Default buffering in binary mode (-1): BufferedReader
38+
fd2 = os.open(filename, os.O_RDONLY)
39+
try:
40+
obj = pyfile_fromfd(fd2, filename, "rb", -1, NULL, NULL, NULL, 0)
41+
try:
42+
self.assertIsInstance(obj, _io.BufferedReader)
43+
self.assertEqual(obj.readline(), FIRST_LINE.encode())
44+
finally:
45+
obj.close()
46+
finally:
47+
os.close(fd2)
48+
49+
# Default buffering in text mode (-1): TextIOWrapper
50+
fd3 = os.open(filename, os.O_RDONLY)
51+
try:
52+
obj = pyfile_fromfd(fd3, filename, "r", -1, NULL, NULL, NULL, 0)
53+
try:
54+
self.assertIsInstance(obj, _io.TextIOWrapper)
55+
self.assertEqual(obj.readline(), FIRST_LINE_NORM)
56+
finally:
57+
obj.close()
58+
finally:
59+
os.close(fd3)
60+
3661
# BufferedReader
3762
fp.seek(0)
3863
obj = pyfile_fromfd(fd, filename, "rb", 1024, NULL, NULL, NULL, 0)
@@ -54,6 +79,27 @@ def test_pyfile_fromfd(self):
5479
finally:
5580
obj.close()
5681

82+
def test_pyfile_fromfd_closefd(self):
83+
# closefd=True should close the underlying file descriptor when the
84+
# returned object is closed
85+
pyfile_fromfd = _testlimitedcapi.pyfile_fromfd
86+
filename = __file__
87+
88+
fd = os.open(filename, os.O_RDONLY)
89+
try:
90+
obj = pyfile_fromfd(fd, filename, "rb", -1, NULL, NULL, NULL, 1)
91+
obj.close()
92+
with self.assertRaises(OSError) as cm:
93+
os.close(fd)
94+
# On POSIX, closing a closed fd raises EBADF
95+
self.assertEqual(cm.exception.errno, errno.EBADF)
96+
finally:
97+
# If the above failed for any reason and fd is still open, close it
98+
try:
99+
os.close(fd)
100+
except OSError:
101+
pass
102+
57103
def test_pyfile_getline(self):
58104
# Test PyFile_GetLine(file, n): call file.readline()
59105
# and strip "\n" suffix if n < 0.

Objects/fileobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const c
3939
open = PyImport_ImportModuleAttrString("_io", "open");
4040
if (open == NULL)
4141
return NULL;
42-
stream = PyObject_CallFunction(open, "isisssO", fd, mode,
42+
stream = PyObject_CallFunction(open, "isizzzO", fd, mode,
4343
buffering, encoding, errors,
4444
newline, closefd ? Py_True : Py_False);
4545
Py_DECREF(open);

0 commit comments

Comments
 (0)