8000 gh-127350: Add more tests for Py_fopen() (GH-128587) · python/cpython@07e6aa2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 07e6aa2

Browse files
gh-127350: Add more tests for Py_fopen() (GH-128587)
1 parent a21e31e commit 07e6aa2

File tree

3 files changed

+33
-25
lines changed

3 files changed

+33
-25
lines changed

Lib/test/test_capi/test_file.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
_testcapi = import_helper.import_module('_testcapi')
77

8+
NULL = None
9+
810

911
class CAPIFileTest(unittest.TestCase):
1012
def test_py_fopen(self):
@@ -25,15 +27,22 @@ def test_py_fopen(self):
2527
os_helper.TESTFN,
2628
os.fsencode(os_helper.TESTFN),
2729
]
28-
# TESTFN_UNDECODABLE cannot be used to create a file on macOS/WASI.
30+
if os_helper.TESTFN_UNDECODABLE is not None:
31+
filenames.append(os_helper.TESTFN_UNDECODABLE)
32+
filenames.append(os.fsdecode(os_helper.TESTFN_UNDECODABLE))
2933
if os_helper.TESTFN_UNENCODABLE is not None:
3034
filenames.append(os_helper.TESTFN_UNENCODABLE)
3135
for filename in filenames:
3236
with self.subTest(filename=filename):
3337
try:
3438
with open(filename, "wb") as fp:
3539
fp.write(source)
36-
40+
except OSError:
41+
# TESTFN_UNDECODABLE cannot be used to create a file
42+
# on macOS/WASI.
43+
filename = None
44+
continue
45+
try:
3746
data = _testcapi.py_fopen(filename, "rb")
3847
self.assertEqual(data, source[:256])
3948
finally:
@@ -47,7 +56,14 @@ def test_py_fopen(self):
4756

4857
# non-ASCII mode failing with "Invalid argument"
4958
with self.assertRaises(OSError):
50-
_testcapi.py_fopen(__file__, "\xe9")
59+
_testcapi.py_fopen(__file__, b"\xc2\x80")
60+
with self.assertRaises(OSError):
61+
# \x98 is invalid in cp1250, cp1251, cp1257
62+
# \x9d is invalid in cp1252-cp1255, cp1258
63+
_testcapi.py_fopen(__file__, b"\xc2\x98\xc2\x9d")
64+
# UnicodeDecodeError can come from the audit hook code
65+
with self.assertRaises((UnicodeDecodeError, OSError)):
66+
_testcapi.py_fopen(__file__, b"\x98\x9d")
5167

5268
# invalid filename type
5369
for invalid_type in (123, object()):
@@ -60,7 +76,8 @@ def test_py_fopen(self):
6076
# On Windows, the file mode is limited to 10 characters
6177
_testcapi.py_fopen(__file__, "rt+, ccs=UTF-8")
6278

63-
# CRASHES py_fopen(__file__, None)
79+
# CRASHES _testcapi.py_fopen(NULL, 'rb')
80+
# CRASHES _testcapi.py_fopen(__file__, NULL)
6481

6582

6683
if __name__ == "__main__":

Modules/_testcapi/clinic/file.c.h

Lines changed: 7 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/_testcapi/file.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,18 @@ module _testcapi
1414
_testcapi.py_fopen
1515
1616
path: object
17-
mode: str
17+
mode: str(zeroes=True, accept={robuffer, str, NoneType})
1818
/
1919
2020
Call Py_fopen(), fread(256) and Py_fclose(). Return read bytes.
2121
[clinic start generated code]*/
2222

2323
static PyObject *
24-
_testcapi_py_fopen_impl(PyObject *module, PyObject *path, const char *mode)
25-
/*[clinic end generated code: output=5a900af000f759de input=d7e7b8f0fd151953]*/
24+
_testcapi_py_fopen_impl(PyObject *module, PyObject *path, const char *mode,
25+
Py_ssize_t mode_length)
26+
/*[clinic end generated code: output=69840d0cfd8b7fbb input=f3a579dd7eb60926]*/
2627
{
28+
NULLABLE(path);
2729
FILE *fp = Py_fopen(path, mode);
2830
if (fp == NULL) {
2931
return NULL;

0 commit comments

Comments
 (0)
0