mirror of
https://github.com/python/cpython.git
synced 2026-04-08 21:00:51 +00:00
[3.10] gh-91583: AC: Fix regression for functions with defining_class (GH-91739) (GH-92079)
Argument Clinic now generates the same efficient code as before
adding the defining_class parameter.
(cherry picked from commit a055dac0b4)
This commit is contained in:
parent
adc06cd2d7
commit
62ddbbcfaf
17 changed files with 661 additions and 389 deletions
|
|
@ -636,6 +636,10 @@ def output_templates(self, f):
|
|||
assert parameters
|
||||
assert isinstance(parameters[0].converter, self_converter)
|
||||
del parameters[0]
|
||||
requires_defining_class = False
|
||||
if parameters and isinstance(parameters[0].converter, defining_class_converter):
|
||||
requires_defining_class = True
|
||||
del parameters[0]
|
||||
converters = [p.converter for p in parameters]
|
||||
|
||||
has_option_groups = parameters and (parameters[0].group or parameters[-1].group)
|
||||
|
|
@ -657,10 +661,6 @@ def output_templates(self, f):
|
|||
if not p.is_optional():
|
||||
min_pos = i
|
||||
|
||||
requires_defining_class = any(
|
||||
isinstance(p.converter, defining_class_converter)
|
||||
for p in parameters)
|
||||
|
||||
meth_o = (len(parameters) == 1 and
|
||||
parameters[0].is_positional_only() and
|
||||
not converters[0].is_optional() and
|
||||
|
|
@ -763,24 +763,40 @@ def parser_body(prototype, *fields, declarations=''):
|
|||
return linear_format(output(), parser_declarations=declarations)
|
||||
|
||||
if not parameters:
|
||||
# no parameters, METH_NOARGS
|
||||
if not requires_defining_class:
|
||||
# no parameters, METH_NOARGS
|
||||
flags = "METH_NOARGS"
|
||||
|
||||
flags = "METH_NOARGS"
|
||||
parser_prototype = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored))
|
||||
""")
|
||||
parser_code = []
|
||||
|
||||
parser_prototype = normalize_snippet("""
|
||||
static PyObject *
|
||||
{c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored))
|
||||
""")
|
||||
parser_definition = parser_prototype
|
||||
else:
|
||||
assert not new_or_init
|
||||
|
||||
flags = "METH_METHOD|METH_FASTCALL|METH_KEYWORDS"
|
||||
|
||||
parser_prototype = parser_prototype_def_class
|
||||
return_error = ('return NULL;' if default_return_converter
|
||||
else 'goto exit;')
|
||||
parser_code = [normalize_snippet("""
|
||||
if (nargs) {{
|
||||
PyErr_SetString(PyExc_TypeError, "{name}() takes no arguments");
|
||||
%s
|
||||
}}
|
||||
""" % return_error, indent=4)]
|
||||
|
||||
if default_return_converter:
|
||||
parser_definition = parser_prototype + '\n' + normalize_snippet("""
|
||||
{{
|
||||
return {c_basename}_impl({impl_arguments});
|
||||
}}
|
||||
""")
|
||||
parser_definition = '\n'.join([
|
||||
parser_prototype,
|
||||
'{{',
|
||||
*parser_code,
|
||||
' return {c_basename}_impl({impl_arguments});',
|
||||
'}}'])
|
||||
else:
|
||||
parser_definition = parser_body(parser_prototype)
|
||||
parser_definition = parser_body(parser_prototype, *parser_code)
|
||||
|
||||
elif meth_o:
|
||||
flags = "METH_O"
|
||||
|
|
@ -939,6 +955,9 @@ def parser_body(prototype, *fields, declarations=''):
|
|||
|
||||
add_label = None
|
||||
for i, p in enumerate(parameters):
|
||||
if isinstance(p.converter, defining_class_converter):
|
||||
raise ValueError("defining_class should be the first "
|
||||
"parameter (after self)")
|
||||
displayname = p.get_displayname(i+1)
|
||||
parsearg = p.converter.parse_arg(argname_fmt % i, displayname)
|
||||
if parsearg is None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue