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):
|
||||
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):
|
||||
|
|
|
@ -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[] = {
|
||||
TEST_EMPTY_FUNCTION_METHODDEF
|
||||
MY_INT_FUNC_METHODDEF
|
||||
MY_INT_SUM_METHODDEF
|
||||
MY_FLOAT_SUM_METHODDEF
|
||||
MY_DOUBLE_SUM_METHODDEF
|
||||
GET_FILE_DESCRIPTOR_METHODDEF
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -173,4 +173,37 @@ my_double_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
|||
exit:
|
||||
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'
|
||||
converter = '_PyLong_FileDescriptor_Converter'
|
||||
|
||||
def converter_init(self, *, accept: TypeSet = {int, NoneType}) -> None:
|
||||
self.add_include('pycore_fileutils.h',
|
||||
'_PyLong_FileDescriptor_Converter()')
|
||||
|
||||
def _parse_arg(self, argname: str, displayname: str) -> str | None:
|
||||
return self.format_code("""
|
||||
{paramname} = PyObject_AsFileDescriptor({argname});
|
||||
if ({paramname} == -1) {{{{
|
||||
goto exit;
|
||||
}}}}
|
||||
""",
|
||||
argname=argname)
|
||||
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
|
||||
if limited_capi:
|
||||
return self.format_code("""
|
||||
{paramname} = PyObject_AsFileDescriptor({argname});
|
||||
if ({paramname} < 0) {{{{
|
||||
goto exit;
|
||||
}}}}
|
||||
""",
|
||||
argname=argname)
|
||||
else:
|
||||
self.add_include('pycore_fileutils.h',
|
||||
'_PyLong_FileDescriptor_Converter()')
|
||||
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
|
||||
|
||||
|
||||
class float_converter(CConverter):
|
||||
|
|
Loading…
Reference in New Issue