gh-108494: Argument Clinic: inline parsing code for positional-only parameters in the limited C API (GH-108622)

This commit is contained in:
Serhiy Storchaka 2023-09-03 17:28:14 +03:00 committed by GitHub
parent 55846099b1
commit 1796c191b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 555 additions and 307 deletions

View file

@ -26,7 +26,6 @@ _io__BufferedIOBase_readinto(PyObject *self, PyObject *arg)
Py_buffer buffer = {NULL, NULL}; Py_buffer buffer = {NULL, NULL};
if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) {
PyErr_Clear();
_PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg);
goto exit; goto exit;
} }
@ -63,7 +62,6 @@ _io__BufferedIOBase_readinto1(PyObject *self, PyObject *arg)
Py_buffer buffer = {NULL, NULL}; Py_buffer buffer = {NULL, NULL};
if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) {
PyErr_Clear();
_PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg);
goto exit; goto exit;
} }
@ -590,7 +588,6 @@ _io__Buffered_readinto(buffered *self, PyObject *arg)
Py_buffer buffer = {NULL, NULL}; Py_buffer buffer = {NULL, NULL};
if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) {
PyErr_Clear();
_PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg);
goto exit; goto exit;
} }
@ -627,7 +624,6 @@ _io__Buffered_readinto1(buffered *self, PyObject *arg)
Py_buffer buffer = {NULL, NULL}; Py_buffer buffer = {NULL, NULL};
if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) {
PyErr_Clear();
_PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg);
goto exit; goto exit;
} }
@ -1098,4 +1094,4 @@ skip_optional_pos:
exit: exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=9e09091995ae02b0 input=a9049054013a1b77]*/ /*[clinic end generated code: output=f940cea085f0bf91 input=a9049054013a1b77]*/

View file

@ -328,7 +328,6 @@ _io_BytesIO_readinto(bytesio *self, PyObject *arg)
Py_buffer buffer = {NULL, NULL}; Py_buffer buffer = {NULL, NULL};
if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) {
PyErr_Clear();
_PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg);
goto exit; goto exit;
} }
@ -538,4 +537,4 @@ skip_optional_pos:
exit: exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=8ab65edc03edbfe0 input=a9049054013a1b77]*/ /*[clinic end generated code: output=b753fdf1ba36c461 input=a9049054013a1b77]*/

View file

@ -245,7 +245,6 @@ _io_FileIO_readinto(fileio *self, PyTypeObject *cls, PyObject *const *args, Py_s
goto exit; goto exit;
} }
if (PyObject_GetBuffer(args[0], &buffer, PyBUF_WRITABLE) < 0) { if (PyObject_GetBuffer(args[0], &buffer, PyBUF_WRITABLE) < 0) {
PyErr_Clear();
_PyArg_BadArgument("readinto", "argument 1", "read-write bytes-like object", args[0]); _PyArg_BadArgument("readinto", "argument 1", "read-write bytes-like object", args[0]);
goto exit; goto exit;
} }
@ -536,4 +535,4 @@ _io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored))
#ifndef _IO_FILEIO_TRUNCATE_METHODDEF #ifndef _IO_FILEIO_TRUNCATE_METHODDEF
#define _IO_FILEIO_TRUNCATE_METHODDEF #define _IO_FILEIO_TRUNCATE_METHODDEF
#endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */ #endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */
/*[clinic end generated code: output=238dd48819076434 input=a9049054013a1b77]*/ /*[clinic end generated code: output=2ce6ce923ccef86e input=a9049054013a1b77]*/

View file

@ -243,7 +243,6 @@ _io__WindowsConsoleIO_readinto(winconsoleio *self, PyTypeObject *cls, PyObject *
goto exit; goto exit;
} }
if (PyObject_GetBuffer(args[0], &buffer, PyBUF_WRITABLE) < 0) { if (PyObject_GetBuffer(args[0], &buffer, PyBUF_WRITABLE) < 0) {
PyErr_Clear();
_PyArg_BadArgument("readinto", "argument 1", "read-write bytes-like object", args[0]); _PyArg_BadArgument("readinto", "argument 1", "read-write bytes-like object", args[0]);
goto exit; goto exit;
} }
@ -465,4 +464,4 @@ _io__WindowsConsoleIO_isatty(winconsoleio *self, PyObject *Py_UNUSED(ignored))
#ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF
#define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF
#endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */ #endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */
/*[clinic end generated code: output=7be51d48ddb7c8c8 input=a9049054013a1b77]*/ /*[clinic end generated code: output=37febc4c96732b3b input=a9049054013a1b77]*/

View file

@ -14,16 +14,17 @@ class HANDLE_converter(CConverter):
type = "HANDLE" type = "HANDLE"
format_unit = '"F_HANDLE"' format_unit = '"F_HANDLE"'
def parse_arg(self, argname, displayname): def parse_arg(self, argname, displayname, *, limited_capi):
return """ return self.format_code("""
{paramname} = PyLong_AsVoidPtr({argname}); {paramname} = PyLong_AsVoidPtr({argname});
if (!{paramname} && PyErr_Occurred()) {{{{ if (!{paramname} && PyErr_Occurred()) {{{{
goto exit; goto exit;
}}}} }}}}
""".format(argname=argname, paramname=self.parser_name) """,
argname=argname)
[python start generated code]*/ [python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=3e537d244034affb]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=3cf0318efc6a8772]*/
/*[clinic input] /*[clinic input]
module _multiprocessing module _multiprocessing

View file

@ -87,15 +87,16 @@ class pid_t_converter(CConverter):
type = 'pid_t' type = 'pid_t'
format_unit = '" _Py_PARSE_PID "' format_unit = '" _Py_PARSE_PID "'
def parse_arg(self, argname, displayname): def parse_arg(self, argname, displayname, *, limited_capi):
return """ return self.format_code("""
{paramname} = PyLong_AsPid({argname}); {paramname} = PyLong_AsPid({argname});
if ({paramname} == -1 && PyErr_Occurred()) {{{{ if ({paramname} == -1 && PyErr_Occurred()) {{{{
goto exit; goto exit;
}}}} }}}}
""".format(argname=argname, paramname=self.parser_name) """,
argname=argname)
[python start generated code]*/ [python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=5af1c116d56cbb5a]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=c94349aa1aad151d]*/
#include "clinic/_posixsubprocess.c.h" #include "clinic/_posixsubprocess.c.h"

View file

@ -110,18 +110,20 @@ class cache_struct_converter(CConverter):
c_default = "NULL" c_default = "NULL"
broken_limited_capi = True broken_limited_capi = True
def parse_arg(self, argname, displayname): def parse_arg(self, argname, displayname, *, limited_capi):
return """ assert not limited_capi
return self.format_code("""
if (!{converter}(module, {argname}, &{paramname})) {{{{ if (!{converter}(module, {argname}, &{paramname})) {{{{
goto exit; goto exit;
}}}} }}}}
""".format(argname=argname, paramname=self.name, """,
converter=self.converter) argname=argname,
converter=self.converter)
def cleanup(self): def cleanup(self):
return "Py_XDECREF(%s);\n" % self.name return "Py_XDECREF(%s);\n" % self.name
[python start generated code]*/ [python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=14e83804f599ed8f]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=c33b27d6b06006c6]*/
static int cache_struct_converter(PyObject *, PyObject *, PyStructObject **); static int cache_struct_converter(PyObject *, PyObject *, PyStructObject **);

View file

@ -37,7 +37,8 @@ my_int_func(PyObject *module, PyObject *arg_)
int arg; int arg;
int _return_value; int _return_value;
if (!PyArg_Parse(arg_, "i:my_int_func", &arg)) { arg = PyLong_AsInt(arg_);
if (arg == -1 && PyErr_Occurred()) {
goto exit; goto exit;
} }
_return_value = my_int_func_impl(module, arg); _return_value = my_int_func_impl(module, arg);
@ -56,22 +57,31 @@ PyDoc_STRVAR(my_int_sum__doc__,
"\n"); "\n");
#define MY_INT_SUM_METHODDEF \ #define MY_INT_SUM_METHODDEF \
{"my_int_sum", (PyCFunction)my_int_sum, METH_VARARGS, my_int_sum__doc__}, {"my_int_sum", (PyCFunction)(void(*)(void))my_int_sum, METH_FASTCALL, my_int_sum__doc__},
static int static int
my_int_sum_impl(PyObject *module, int x, int y); my_int_sum_impl(PyObject *module, int x, int y);
static PyObject * static PyObject *
my_int_sum(PyObject *module, PyObject *args) my_int_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
int x; int x;
int y; int y;
int _return_value; int _return_value;
if (!PyArg_ParseTuple(args, "ii:my_int_sum", if (nargs != 2) {
&x, &y)) PyErr_Format(PyExc_TypeError, "my_int_sum expected 2 arguments, got %zd", nargs);
goto exit; goto exit;
}
x = PyLong_AsInt(args[0]);
if (x == -1 && PyErr_Occurred()) {
goto exit;
}
y = PyLong_AsInt(args[1]);
if (y == -1 && PyErr_Occurred()) {
goto exit;
}
_return_value = my_int_sum_impl(module, x, y); _return_value = my_int_sum_impl(module, x, y);
if ((_return_value == -1) && PyErr_Occurred()) { if ((_return_value == -1) && PyErr_Occurred()) {
goto exit; goto exit;
@ -81,4 +91,4 @@ my_int_sum(PyObject *module, PyObject *args)
exit: exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=dcd5203d0d29df3a input=a9049054013a1b77]*/ /*[clinic end generated code: output=5cf64baf978d2288 input=a9049054013a1b77]*/

View file

@ -38,13 +38,14 @@
class pointer_converter(CConverter): class pointer_converter(CConverter):
format_unit = '"F_POINTER"' format_unit = '"F_POINTER"'
def parse_arg(self, argname, displayname): def parse_arg(self, argname, displayname, *, limited_capi):
return """ return self.format_code("""
{paramname} = PyLong_AsVoidPtr({argname}); {paramname} = PyLong_AsVoidPtr({argname});
if (!{paramname} && PyErr_Occurred()) {{{{ if (!{paramname} && PyErr_Occurred()) {{{{
goto exit; goto exit;
}}}} }}}}
""".format(argname=argname, paramname=self.parser_name) """,
argname=argname)
class OVERLAPPED_converter(pointer_converter): class OVERLAPPED_converter(pointer_converter):
type = 'OVERLAPPED *' type = 'OVERLAPPED *'
@ -55,13 +56,14 @@ class HANDLE_converter(pointer_converter):
class ULONG_PTR_converter(pointer_converter): class ULONG_PTR_converter(pointer_converter):
type = 'ULONG_PTR' type = 'ULONG_PTR'
def parse_arg(self, argname, displayname): def parse_arg(self, argname, displayname, *, limited_capi):
return """ return self.format_code("""
{paramname} = (uintptr_t)PyLong_AsVoidPtr({argname}); {paramname} = (uintptr_t)PyLong_AsVoidPtr({argname});
if (!{paramname} && PyErr_Occurred()) {{{{ if (!{paramname} && PyErr_Occurred()) {{{{
goto exit; goto exit;
}}}} }}}}
""".format(argname=argname, paramname=self.parser_name) """,
argname=argname)
class DWORD_converter(unsigned_long_converter): class DWORD_converter(unsigned_long_converter):
type = 'DWORD' type = 'DWORD'
@ -69,7 +71,7 @@ class DWORD_converter(unsigned_long_converter):
class BOOL_converter(int_converter): class BOOL_converter(int_converter):
type = 'BOOL' type = 'BOOL'
[python start generated code]*/ [python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=8a07ea3018f4cec8]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=436f4440630a304c]*/
/*[clinic input] /*[clinic input]
module _overlapped module _overlapped

View file

@ -23,15 +23,16 @@ class pid_t_converter(CConverter):
type = 'pid_t' type = 'pid_t'
format_unit = '" _Py_PARSE_PID "' format_unit = '" _Py_PARSE_PID "'
def parse_arg(self, argname, displayname): def parse_arg(self, argname, displayname, *, limited_capi):
return """ return self.format_code("""
{paramname} = PyLong_AsPid({argname}); {paramname} = PyLong_AsPid({argname});
if ({paramname} == -1 && PyErr_Occurred()) {{{{ if ({paramname} == -1 && PyErr_Occurred()) {{{{
goto exit; goto exit;
}}}} }}}}
""".format(argname=argname, paramname=self.parser_name) """,
argname=argname)
[python start generated code]*/ [python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=5af1c116d56cbb5a]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=c94349aa1aad151d]*/
#include "clinic/resource.c.h" #include "clinic/resource.c.h"

View file

@ -38,13 +38,14 @@ class HANDLE_converter(CConverter):
type = 'void *' type = 'void *'
format_unit = '"_Py_PARSE_UINTPTR"' format_unit = '"_Py_PARSE_UINTPTR"'
def parse_arg(self, argname, displayname): def parse_arg(self, argname, displayname, *, limited_capi):
return """ return self.format_code("""
{paramname} = PyLong_AsVoidPtr({argname}); {paramname} = PyLong_AsVoidPtr({argname});
if (!{paramname} && PyErr_Occurred()) {{{{ if (!{paramname} && PyErr_Occurred()) {{{{
goto exit; goto exit;
}}}} }}}}
""".format(argname=argname, paramname=self.parser_name) """,
argname=argname)
class HANDLE_return_converter(CReturnConverter): class HANDLE_return_converter(CReturnConverter):
type = 'void *' type = 'void *'
@ -74,7 +75,7 @@ class wchar_t_return_converter(CReturnConverter):
data.return_conversion.append( data.return_conversion.append(
'return_value = PyUnicode_FromOrdinal(_return_value);\n') 'return_value = PyUnicode_FromOrdinal(_return_value);\n')
[python start generated code]*/ [python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=1e8e9fa3538ec08f]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=ff031be44ab3250d]*/
/*[clinic input] /*[clinic input]
module msvcrt module msvcrt

View file

@ -222,13 +222,15 @@ class HKEY_converter(CConverter):
converter = 'clinic_HKEY_converter' converter = 'clinic_HKEY_converter'
broken_limited_capi = True broken_limited_capi = True
def parse_arg(self, argname, displayname): def parse_arg(self, argname, displayname, *, limited_capi):
return """ assert not limited_capi
if (!{converter}(_PyModule_GetState(module), {argname}, &{paramname})) {{{{ return self.format_code("""
goto exit; if (!{converter}(_PyModule_GetState(module), {argname}, &{paramname})) {{{{
}}}} goto exit;
""".format(argname=argname, paramname=self.parser_name, }}}}
converter=self.converter) """,
argname=argname,
converter=self.converter)
class HKEY_return_converter(CReturnConverter): class HKEY_return_converter(CReturnConverter):
type = 'HKEY' type = 'HKEY'
@ -250,7 +252,7 @@ class self_return_converter(CReturnConverter):
data.return_conversion.append( data.return_conversion.append(
'return_value = (PyObject *)_return_value;\n') 'return_value = (PyObject *)_return_value;\n')
[python start generated code]*/ [python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=f8cb7034338aeaba]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=4979f33998ffb6f8]*/
#include "clinic/winreg.c.h" #include "clinic/winreg.c.h"

File diff suppressed because it is too large Load diff