mirror of
https://github.com/python/cpython.git
synced 2026-01-04 06:22:20 +00:00
gh-127350: Add more tests for Py_fopen() (GH-128587)
This commit is contained in:
parent
a21e31ec54
commit
07e6aa2efc
3 changed files with 33 additions and 25 deletions
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
_testcapi = import_helper.import_module('_testcapi')
|
||||
|
||||
NULL = None
|
||||
|
||||
|
||||
class CAPIFileTest(unittest.TestCase):
|
||||
def test_py_fopen(self):
|
||||
|
|
@ -25,7 +27,9 @@ def test_py_fopen(self):
|
|||
os_helper.TESTFN,
|
||||
os.fsencode(os_helper.TESTFN),
|
||||
]
|
||||
# TESTFN_UNDECODABLE cannot be used to create a file on macOS/WASI.
|
||||
if os_helper.TESTFN_UNDECODABLE is not None:
|
||||
filenames.append(os_helper.TESTFN_UNDECODABLE)
|
||||
filenames.append(os.fsdecode(os_helper.TESTFN_UNDECODABLE))
|
||||
if os_helper.TESTFN_UNENCODABLE is not None:
|
||||
filenames.append(os_helper.TESTFN_UNENCODABLE)
|
||||
for filename in filenames:
|
||||
|
|
@ -33,7 +37,12 @@ def test_py_fopen(self):
|
|||
try:
|
||||
with open(filename, "wb") as fp:
|
||||
fp.write(source)
|
||||
|
||||
except OSError:
|
||||
# TESTFN_UNDECODABLE cannot be used to create a file
|
||||
# on macOS/WASI.
|
||||
filename = None
|
||||
continue
|
||||
try:
|
||||
data = _testcapi.py_fopen(filename, "rb")
|
||||
self.assertEqual(data, source[:256])
|
||||
finally:
|
||||
|
|
@ -47,7 +56,14 @@ def test_py_fopen(self):
|
|||
|
||||
# non-ASCII mode failing with "Invalid argument"
|
||||
with self.assertRaises(OSError):
|
||||
_testcapi.py_fopen(__file__, "\xe9")
|
||||
_testcapi.py_fopen(__file__, b"\xc2\x80")
|
||||
with self.assertRaises(OSError):
|
||||
# \x98 is invalid in cp1250, cp1251, cp1257
|
||||
# \x9d is invalid in cp1252-cp1255, cp1258
|
||||
_testcapi.py_fopen(__file__, b"\xc2\x98\xc2\x9d")
|
||||
# UnicodeDecodeError can come from the audit hook code
|
||||
with self.assertRaises((UnicodeDecodeError, OSError)):
|
||||
_testcapi.py_fopen(__file__, b"\x98\x9d")
|
||||
|
||||
# invalid filename type
|
||||
for invalid_type in (123, object()):
|
||||
|
|
@ -60,7 +76,8 @@ def test_py_fopen(self):
|
|||
# On Windows, the file mode is limited to 10 characters
|
||||
_testcapi.py_fopen(__file__, "rt+, ccs=UTF-8")
|
||||
|
||||
# CRASHES py_fopen(__file__, None)
|
||||
# CRASHES _testcapi.py_fopen(NULL, 'rb')
|
||||
# CRASHES _testcapi.py_fopen(__file__, NULL)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
25
Modules/_testcapi/clinic/file.c.h
generated
25
Modules/_testcapi/clinic/file.c.h
generated
|
|
@ -14,7 +14,8 @@ PyDoc_STRVAR(_testcapi_py_fopen__doc__,
|
|||
{"py_fopen", _PyCFunction_CAST(_testcapi_py_fopen), METH_FASTCALL, _testcapi_py_fopen__doc__},
|
||||
|
||||
static PyObject *
|
||||
_testcapi_py_fopen_impl(PyObject *module, PyObject *path, const char *mode);
|
||||
_testcapi_py_fopen_impl(PyObject *module, PyObject *path, const char *mode,
|
||||
Py_ssize_t mode_length);
|
||||
|
||||
static PyObject *
|
||||
_testcapi_py_fopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||
|
|
@ -22,27 +23,15 @@ _testcapi_py_fopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
|||
PyObject *return_value = NULL;
|
||||
PyObject *path;
|
||||
const char *mode;
|
||||
|
||||
if (!_PyArg_CheckPositional("py_fopen", nargs, 2, 2)) {
|
||||
goto exit;
|
||||
}
|
||||
path = args[0];
|
||||
if (!PyUnicode_Check(args[1])) {
|
||||
_PyArg_BadArgument("py_fopen", "argument 2", "str", args[1]);
|
||||
goto exit;
|
||||
}
|
||||
Py_ssize_t mode_length;
|
||||
mode = PyUnicode_AsUTF8AndSize(args[1], &mode_length);
|
||||
if (mode == NULL) {
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, "Oz#:py_fopen",
|
||||
&path, &mode, &mode_length)) {
|
||||
goto exit;
|
||||
}
|
||||
if (strlen(mode) != (size_t)mode_length) {
|
||||
PyErr_SetString(PyExc_ValueError, "embedded null character");
|
||||
goto exit;
|
||||
}
|
||||
return_value = _testcapi_py_fopen_impl(module, path, mode);
|
||||
return_value = _testcapi_py_fopen_impl(module, path, mode, mode_length);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=c9fe964c3e5a0c32 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=c4dc92400306c3eb input=a9049054013a1b77]*/
|
||||
|
|
|
|||
|
|
@ -14,16 +14,18 @@ module _testcapi
|
|||
_testcapi.py_fopen
|
||||
|
||||
path: object
|
||||
mode: str
|
||||
mode: str(zeroes=True, accept={robuffer, str, NoneType})
|
||||
/
|
||||
|
||||
Call Py_fopen(), fread(256) and Py_fclose(). Return read bytes.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_testcapi_py_fopen_impl(PyObject *module, PyObject *path, const char *mode)
|
||||
/*[clinic end generated code: output=5a900af000f759de input=d7e7b8f0fd151953]*/
|
||||
_testcapi_py_fopen_impl(PyObject *module, PyObject *path, const char *mode,
|
||||
Py_ssize_t mode_length)
|
||||
/*[clinic end generated code: output=69840d0cfd8b7fbb input=f3a579dd7eb60926]*/
|
||||
{
|
||||
NULLABLE(path);
|
||||
FILE *fp = Py_fopen(path, mode);
|
||||
if (fp == NULL) {
|
||||
return NULL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue