mirror of
https://github.com/python/cpython.git
synced 2025-12-09 10:37:17 +00:00
gh-104683: Make Argument Clinic template strings class level members (#107556)
The motivation for this change is to clean up the output_templates() method a little bit, as it accounts for ~10% of the lines of code in clinic.py; removing some clutter helps readability.
This commit is contained in:
parent
af8141cf87
commit
bcdd307231
1 changed files with 69 additions and 71 deletions
|
|
@ -760,6 +760,59 @@ class CLanguage(Language):
|
|||
stop_line = "[{dsl_name} start generated code]*/"
|
||||
checksum_line = "/*[{dsl_name} end generated code: {arguments}]*/"
|
||||
|
||||
PARSER_PROTOTYPE_KEYWORD: Final[str] = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs)
|
||||
""")
|
||||
PARSER_PROTOTYPE_KEYWORD___INIT__: Final[str] = normalize_snippet("""
|
||||
static int
|
||||
{c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs)
|
||||
""")
|
||||
PARSER_PROTOTYPE_VARARGS: Final[str] = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *args)
|
||||
""")
|
||||
PARSER_PROTOTYPE_FASTCALL: Final[str] = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *const *args, Py_ssize_t nargs)
|
||||
""")
|
||||
PARSER_PROTOTYPE_FASTCALL_KEYWORDS: Final[str] = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
""")
|
||||
PARSER_PROTOTYPE_DEF_CLASS: Final[str] = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyTypeObject *{defining_class_name}, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
""")
|
||||
PARSER_PROTOTYPE_NOARGS: Final[str] = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored))
|
||||
""")
|
||||
METH_O_PROTOTYPE: Final[str] = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({impl_parameters})
|
||||
""")
|
||||
DOCSTRING_PROTOTYPE_VAR: Final[str] = normalize_snippet("""
|
||||
PyDoc_VAR({c_basename}__doc__);
|
||||
""")
|
||||
DOCSTRING_PROTOTYPE_STRVAR: Final[str] = normalize_snippet("""
|
||||
PyDoc_STRVAR({c_basename}__doc__,
|
||||
{docstring});
|
||||
""")
|
||||
IMPL_DEFINITION_PROTOTYPE: Final[str] = normalize_snippet("""
|
||||
static {impl_return_type}
|
||||
{c_basename}_impl({impl_parameters})
|
||||
""")
|
||||
METHODDEF_PROTOTYPE_DEFINE: Final[str] = normalize_snippet(r"""
|
||||
#define {methoddef_name} \
|
||||
{{"{name}", {methoddef_cast}{c_basename}{methoddef_cast_end}, {methoddef_flags}, {c_basename}__doc__}},
|
||||
""")
|
||||
METHODDEF_PROTOTYPE_IFNDEF: Final[str] = normalize_snippet("""
|
||||
#ifndef {methoddef_name}
|
||||
#define {methoddef_name}
|
||||
#endif /* !defined({methoddef_name}) */
|
||||
""")
|
||||
|
||||
def __init__(self, filename: str) -> None:
|
||||
super().__init__(filename)
|
||||
self.cpp = cpp.Monitor(filename)
|
||||
|
|
@ -862,52 +915,15 @@ class CLanguage(Language):
|
|||
# methoddef_ifndef
|
||||
|
||||
return_value_declaration = "PyObject *return_value = NULL;"
|
||||
|
||||
methoddef_define = normalize_snippet("""
|
||||
#define {methoddef_name} \\
|
||||
{{"{name}", {methoddef_cast}{c_basename}{methoddef_cast_end}, {methoddef_flags}, {c_basename}__doc__}},
|
||||
""")
|
||||
methoddef_define = self.METHODDEF_PROTOTYPE_DEFINE
|
||||
if new_or_init and not f.docstring:
|
||||
docstring_prototype = docstring_definition = ''
|
||||
else:
|
||||
docstring_prototype = normalize_snippet("""
|
||||
PyDoc_VAR({c_basename}__doc__);
|
||||
""")
|
||||
docstring_definition = normalize_snippet("""
|
||||
PyDoc_STRVAR({c_basename}__doc__,
|
||||
{docstring});
|
||||
""")
|
||||
impl_definition = normalize_snippet("""
|
||||
static {impl_return_type}
|
||||
{c_basename}_impl({impl_parameters})
|
||||
""")
|
||||
docstring_prototype = self.DOCSTRING_PROTOTYPE_VAR
|
||||
docstring_definition = self.DOCSTRING_PROTOTYPE_STRVAR
|
||||
impl_definition = self.IMPL_DEFINITION_PROTOTYPE
|
||||
impl_prototype = parser_prototype = parser_definition = None
|
||||
|
||||
parser_prototype_keyword = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs)
|
||||
""")
|
||||
|
||||
parser_prototype_varargs = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *args)
|
||||
""")
|
||||
|
||||
parser_prototype_fastcall = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *const *args, Py_ssize_t nargs)
|
||||
""")
|
||||
|
||||
parser_prototype_fastcall_keywords = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
""")
|
||||
|
||||
parser_prototype_def_class = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyTypeObject *{defining_class_name}, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
""")
|
||||
|
||||
# parser_body_fields remembers the fields passed in to the
|
||||
# previous call to parser_body. this is used for an awful hack.
|
||||
parser_body_fields: tuple[str, ...] = ()
|
||||
|
|
@ -950,19 +966,13 @@ class CLanguage(Language):
|
|||
if not requires_defining_class:
|
||||
# no parameters, METH_NOARGS
|
||||
flags = "METH_NOARGS"
|
||||
|
||||
parser_prototype = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored))
|
||||
""")
|
||||
parser_prototype = self.PARSER_PROTOTYPE_NOARGS
|
||||
parser_code = []
|
||||
|
||||
else:
|
||||
assert not new_or_init
|
||||
|
||||
flags = "METH_METHOD|METH_FASTCALL|METH_KEYWORDS"
|
||||
|
||||
parser_prototype = parser_prototype_def_class
|
||||
parser_prototype = self.PARSER_PROTOTYPE_DEF_CLASS
|
||||
return_error = ('return NULL;' if default_return_converter
|
||||
else 'goto exit;')
|
||||
parser_code = [normalize_snippet("""
|
||||
|
|
@ -987,10 +997,7 @@ class CLanguage(Language):
|
|||
|
||||
if (isinstance(converters[0], object_converter) and
|
||||
converters[0].format_unit == 'O'):
|
||||
meth_o_prototype = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({impl_parameters})
|
||||
""")
|
||||
meth_o_prototype = self.METH_O_PROTOTYPE
|
||||
|
||||
if default_return_converter:
|
||||
# maps perfectly to METH_O, doesn't need a return converter.
|
||||
|
|
@ -1030,8 +1037,7 @@ class CLanguage(Language):
|
|||
# in a big switch statement)
|
||||
|
||||
flags = "METH_VARARGS"
|
||||
parser_prototype = parser_prototype_varargs
|
||||
|
||||
parser_prototype = self.PARSER_PROTOTYPE_VARARGS
|
||||
parser_definition = parser_body(parser_prototype, ' {option_group_parsing}')
|
||||
|
||||
elif not requires_defining_class and pos_only == len(parameters) - pseudo_args:
|
||||
|
|
@ -1040,7 +1046,7 @@ class CLanguage(Language):
|
|||
# we only need one call to _PyArg_ParseStack
|
||||
|
||||
flags = "METH_FASTCALL"
|
||||
parser_prototype = parser_prototype_fastcall
|
||||
parser_prototype = self.PARSER_PROTOTYPE_FASTCALL
|
||||
nargs = 'nargs'
|
||||
argname_fmt = 'args[%d]'
|
||||
else:
|
||||
|
|
@ -1048,7 +1054,7 @@ class CLanguage(Language):
|
|||
# we only need one call to PyArg_ParseTuple
|
||||
|
||||
flags = "METH_VARARGS"
|
||||
parser_prototype = parser_prototype_varargs
|
||||
parser_prototype = self.PARSER_PROTOTYPE_VARARGS
|
||||
nargs = 'PyTuple_GET_SIZE(args)'
|
||||
argname_fmt = 'PyTuple_GET_ITEM(args, %d)'
|
||||
|
||||
|
|
@ -1145,7 +1151,7 @@ class CLanguage(Language):
|
|||
nargs = f"Py_MIN(nargs, {max_pos})" if max_pos else "0"
|
||||
if not new_or_init:
|
||||
flags = "METH_FASTCALL|METH_KEYWORDS"
|
||||
parser_prototype = parser_prototype_fastcall_keywords
|
||||
parser_prototype = self.PARSER_PROTOTYPE_FASTCALL_KEYWORDS
|
||||
argname_fmt = 'args[%d]'
|
||||
declarations = declare_parser(f)
|
||||
declarations += "\nPyObject *argsbuf[%s];" % len(converters)
|
||||
|
|
@ -1160,7 +1166,7 @@ class CLanguage(Language):
|
|||
else:
|
||||
# positional-or-keyword arguments
|
||||
flags = "METH_VARARGS|METH_KEYWORDS"
|
||||
parser_prototype = parser_prototype_keyword
|
||||
parser_prototype = self.PARSER_PROTOTYPE_KEYWORD
|
||||
argname_fmt = 'fastargs[%d]'
|
||||
declarations = declare_parser(f)
|
||||
declarations += "\nPyObject *argsbuf[%s];" % len(converters)
|
||||
|
|
@ -1177,7 +1183,7 @@ class CLanguage(Language):
|
|||
|
||||
if requires_defining_class:
|
||||
flags = 'METH_METHOD|' + flags
|
||||
parser_prototype = parser_prototype_def_class
|
||||
parser_prototype = self.PARSER_PROTOTYPE_DEF_CLASS
|
||||
|
||||
add_label: str | None = None
|
||||
for i, p in enumerate(parameters):
|
||||
|
|
@ -1264,13 +1270,10 @@ class CLanguage(Language):
|
|||
methoddef_define = ''
|
||||
|
||||
if f.kind is METHOD_NEW:
|
||||
parser_prototype = parser_prototype_keyword
|
||||
parser_prototype = self.PARSER_PROTOTYPE_KEYWORD
|
||||
else:
|
||||
return_value_declaration = "int return_value = -1;"
|
||||
parser_prototype = normalize_snippet("""
|
||||
static int
|
||||
{c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs)
|
||||
""")
|
||||
parser_prototype = self.PARSER_PROTOTYPE_KEYWORD___INIT__
|
||||
|
||||
fields = list(parser_body_fields)
|
||||
parses_positional = 'METH_NOARGS' not in flags
|
||||
|
|
@ -1323,12 +1326,7 @@ class CLanguage(Language):
|
|||
|
||||
if methoddef_define and f.full_name not in clinic.ifndef_symbols:
|
||||
clinic.ifndef_symbols.add(f.full_name)
|
||||
methoddef_ifndef = normalize_snippet("""
|
||||
#ifndef {methoddef_name}
|
||||
#define {methoddef_name}
|
||||
#endif /* !defined({methoddef_name}) */
|
||||
""")
|
||||
|
||||
methoddef_ifndef = self.METHODDEF_PROTOTYPE_IFNDEF
|
||||
|
||||
# add ';' to the end of parser_prototype and impl_prototype
|
||||
# (they mustn't be None, but they could be an empty string.)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue