mirror of https://github.com/python/cpython
gh-116646: Add limited C API support to AC fildes converter (#116769)
Add tests on the "fildes" converter to _testclinic_limited.
This commit is contained in:
parent
a18c9854e8
commit
d4028724f2
|
@ -3698,6 +3698,39 @@ class LimitedCAPIFunctionalTest(unittest.TestCase):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
func(1., "2")
|
func(1., "2")
|
||||||
|
|
||||||
|
def test_get_file_descriptor(self):
|
||||||
|
# test 'file descriptor' converter: call PyObject_AsFileDescriptor()
|
||||||
|
get_fd = _testclinic_limited.get_file_descriptor
|
||||||
|
|
||||||
|
class MyInt(int):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MyFile:
|
||||||
|
def __init__(self, fd):
|
||||||
|
self._fd = fd
|
||||||
|
def fileno(self):
|
||||||
|
return self._fd
|
||||||
|
|
||||||
|
for fd in (0, 1, 2, 5, 123_456):
|
||||||
|
self.assertEqual(get_fd(fd), fd)
|
||||||
|
|
||||||
|
myint = MyInt(fd)
|
||||||
|
self.assertEqual(get_fd(myint), fd)
|
||||||
|
|
||||||
|
myfile = MyFile(fd)
|
||||||
|
self.assertEqual(get_fd(myfile), fd)
|
||||||
|
|
||||||
|
with self.assertRaises(OverflowError):
|
||||||
|
get_fd(2**256)
|
||||||
|
with self.assertWarnsRegex(RuntimeWarning,
|
||||||
|
"bool is used as a file descriptor"):
|
||||||
|
get_fd(True)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
get_fd(1.0)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
get_fd("abc")
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
get_fd(None)
|
||||||
|
|
||||||
|
|
||||||
class PermutationTests(unittest.TestCase):
|
class PermutationTests(unittest.TestCase):
|
||||||
|
|
|
@ -105,12 +105,30 @@ my_double_sum_impl(PyObject *module, double x, double y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
get_file_descriptor -> int
|
||||||
|
|
||||||
|
file as fd: fildes
|
||||||
|
/
|
||||||
|
|
||||||
|
Get a file descriptor.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_file_descriptor_impl(PyObject *module, int fd)
|
||||||
|
/*[clinic end generated code: output=80051ebad54db8a8 input=82e2a1418848cd5b]*/
|
||||||
|
{
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef tester_methods[] = {
|
static PyMethodDef tester_methods[] = {
|
||||||
TEST_EMPTY_FUNCTION_METHODDEF
|
TEST_EMPTY_FUNCTION_METHODDEF
|
||||||
MY_INT_FUNC_METHODDEF
|
MY_INT_FUNC_METHODDEF
|
||||||
MY_INT_SUM_METHODDEF
|
MY_INT_SUM_METHODDEF
|
||||||
MY_FLOAT_SUM_METHODDEF
|
MY_FLOAT_SUM_METHODDEF
|
||||||
MY_DOUBLE_SUM_METHODDEF
|
MY_DOUBLE_SUM_METHODDEF
|
||||||
|
GET_FILE_DESCRIPTOR_METHODDEF
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -173,4 +173,37 @@ my_double_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=bb9f6b8c5d9e6a79 input=a9049054013a1b77]*/
|
|
||||||
|
PyDoc_STRVAR(get_file_descriptor__doc__,
|
||||||
|
"get_file_descriptor($module, file, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Get a file descriptor.");
|
||||||
|
|
||||||
|
#define GET_FILE_DESCRIPTOR_METHODDEF \
|
||||||
|
{"get_file_descriptor", (PyCFunction)get_file_descriptor, METH_O, get_file_descriptor__doc__},
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_file_descriptor_impl(PyObject *module, int fd);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
get_file_descriptor(PyObject *module, PyObject *arg)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
int fd;
|
||||||
|
int _return_value;
|
||||||
|
|
||||||
|
fd = PyObject_AsFileDescriptor(arg);
|
||||||
|
if (fd < 0) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
_return_value = get_file_descriptor_impl(module, fd);
|
||||||
|
if ((_return_value == -1) && PyErr_Occurred()) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = PyLong_FromLong((long)_return_value);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
/*[clinic end generated code: output=03fd7811c056dc74 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -3800,18 +3800,19 @@ class fildes_converter(CConverter):
|
||||||
type = 'int'
|
type = 'int'
|
||||||
converter = '_PyLong_FileDescriptor_Converter'
|
converter = '_PyLong_FileDescriptor_Converter'
|
||||||
|
|
||||||
def converter_init(self, *, accept: TypeSet = {int, NoneType}) -> None:
|
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
|
||||||
self.add_include('pycore_fileutils.h',
|
if limited_capi:
|
||||||
'_PyLong_FileDescriptor_Converter()')
|
return self.format_code("""
|
||||||
|
{paramname} = PyObject_AsFileDescriptor({argname});
|
||||||
def _parse_arg(self, argname: str, displayname: str) -> str | None:
|
if ({paramname} < 0) {{{{
|
||||||
return self.format_code("""
|
goto exit;
|
||||||
{paramname} = PyObject_AsFileDescriptor({argname});
|
}}}}
|
||||||
if ({paramname} == -1) {{{{
|
""",
|
||||||
goto exit;
|
argname=argname)
|
||||||
}}}}
|
else:
|
||||||
""",
|
self.add_include('pycore_fileutils.h',
|
||||||
argname=argname)
|
'_PyLong_FileDescriptor_Converter()')
|
||||||
|
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
|
||||||
|
|
||||||
|
|
||||||
class float_converter(CConverter):
|
class float_converter(CConverter):
|
||||||
|
|
Loading…
Reference in New Issue