gh-132162: Add tests for Py_UniversalNewlineFgets() (#132164)

This commit is contained in:
alexey semenyuk 2025-04-24 20:43:48 +05:00 committed by GitHub
parent 06a26fda60
commit d7365e6050
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 98 additions and 2 deletions

View file

@ -294,7 +294,28 @@ class CAPIFileTest(unittest.TestCase):
# CRASHES py_fopen(NULL, 'rb')
# CRASHES py_fopen(__file__, NULL)
# TODO: Test Py_UniversalNewlineFgets()
def test_py_universalnewlinefgets(self):
py_universalnewlinefgets = _testcapi.py_universalnewlinefgets
filename = os_helper.TESTFN
self.addCleanup(os_helper.unlink, filename)
with open(filename, "wb") as fp:
fp.write(b"line1\nline2")
line = py_universalnewlinefgets(filename, 1000)
self.assertEqual(line, b"line1\n")
with open(filename, "wb") as fp:
fp.write(b"line2\r\nline3")
line = py_universalnewlinefgets(filename, 1000)
self.assertEqual(line, b"line2\n")
with open(filename, "wb") as fp:
fp.write(b"line3\rline4")
line = py_universalnewlinefgets(filename, 1000)
self.assertEqual(line, b"line3\n")
# PyFile_SetOpenCodeHook() and PyFile_OpenCode() are tested by
# test_embed.test_open_code_hook()

View file

@ -61,4 +61,38 @@ _testcapi_py_fopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
/*[clinic end generated code: output=e943bbd7f181d079 input=a9049054013a1b77]*/
PyDoc_STRVAR(_testcapi_py_universalnewlinefgets__doc__,
"py_universalnewlinefgets($module, file, size, /)\n"
"--\n"
"\n"
"Read a line from a file using Py_UniversalNewlineFgets.");
#define _TESTCAPI_PY_UNIVERSALNEWLINEFGETS_METHODDEF \
{"py_universalnewlinefgets", _PyCFunction_CAST(_testcapi_py_universalnewlinefgets), METH_FASTCALL, _testcapi_py_universalnewlinefgets__doc__},
static PyObject *
_testcapi_py_universalnewlinefgets_impl(PyObject *module, PyObject *file,
int size);
static PyObject *
_testcapi_py_universalnewlinefgets(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
PyObject *file;
int size;
if (!_PyArg_CheckPositional("py_universalnewlinefgets", nargs, 2, 2)) {
goto exit;
}
file = args[0];
size = PyLong_AsInt(args[1]);
if (size == -1 && PyErr_Occurred()) {
goto exit;
}
return_value = _testcapi_py_universalnewlinefgets_impl(module, file, size);
exit:
return return_value;
}
/*[clinic end generated code: output=a5ed111054e3a0bc input=a9049054013a1b77]*/

View file

@ -57,9 +57,50 @@ _testcapi_py_fopen_impl(PyObject *module, PyObject *path, const char *mode,
}
/*[clinic input]
_testcapi.py_universalnewlinefgets
file: object
size: int
/
Read a line from a file using Py_UniversalNewlineFgets.
[clinic start generated code]*/
static PyObject *
_testcapi_py_universalnewlinefgets_impl(PyObject *module, PyObject *file,
int size)
/*[clinic end generated code: output=2ce1bc76c9dc871c input=02c236049d18569a]*/
{
FILE *fp = Py_fopen(file, "rb");
if (fp == NULL) {
return NULL;
}
char *buf = (char *)PyMem_Malloc(size);
if (buf == NULL) {
Py_fclose(fp);
return PyErr_NoMemory();
}
char *result = Py_UniversalNewlineFgets(buf, size, fp, NULL);
if (result == NULL) {
PyMem_Free(buf);
Py_fclose(fp);
Py_RETURN_NONE;
}
PyObject *line = PyBytes_FromString(result);
PyMem_Free(buf);
Py_fclose(fp);
return line;
}
static PyMethodDef test_methods[] = {
_TESTCAPI_PYFILE_NEWSTDPRINTER_METHODDEF
_TESTCAPI_PY_FOPEN_METHODDEF
_TESTCAPI_PY_UNIVERSALNEWLINEFGETS_METHODDEF
{NULL},
};