mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
gh-114258: Argument Clinic: refactor getset implementation (#116170)
* Move param guard to param state machine * Override return converter during parsing * Don't use a custom type slot return converter; instead special case type slot functions during generation.
This commit is contained in:
parent
45a92436c5
commit
cfbdce7208
3 changed files with 18 additions and 35 deletions
|
@ -5004,12 +5004,16 @@ Test_property_set_impl(TestObj *self, PyObject *value);
|
||||||
static int
|
static int
|
||||||
Test_property_set(TestObj *self, PyObject *value, void *Py_UNUSED(context))
|
Test_property_set(TestObj *self, PyObject *value, void *Py_UNUSED(context))
|
||||||
{
|
{
|
||||||
return Test_property_set_impl(self, value);
|
int return_value;
|
||||||
|
|
||||||
|
return_value = Test_property_set_impl(self, value);
|
||||||
|
|
||||||
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Test_property_set_impl(TestObj *self, PyObject *value)
|
Test_property_set_impl(TestObj *self, PyObject *value)
|
||||||
/*[clinic end generated code: output=9797cd03c5204ddb input=3bc3f46a23c83a88]*/
|
/*[clinic end generated code: output=d51023f17c4ac3a1 input=3bc3f46a23c83a88]*/
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
output push
|
output push
|
||||||
|
@ -5327,11 +5331,6 @@ Test__pyarg_parsestackandkeywords_impl(TestObj *self, PyTypeObject *cls,
|
||||||
/*[clinic end generated code: output=4fda8a7f2547137c input=fc72ef4b4cfafabc]*/
|
/*[clinic end generated code: output=4fda8a7f2547137c input=fc72ef4b4cfafabc]*/
|
||||||
|
|
||||||
|
|
||||||
static long
|
|
||||||
Test___init___impl(TestObj *self)
|
|
||||||
/*[clinic end generated code: output=daf6ee12c4e443fb input=311af0dc7f17e8e9]*/
|
|
||||||
|
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
fn_with_default_binop_expr
|
fn_with_default_binop_expr
|
||||||
arg: object(c_default='CONST_A + CONST_B') = a+b
|
arg: object(c_default='CONST_A + CONST_B') = a+b
|
||||||
|
|
|
@ -2175,7 +2175,7 @@ class ClinicParserTest(TestCase):
|
||||||
obj: int
|
obj: int
|
||||||
/
|
/
|
||||||
"""
|
"""
|
||||||
expected_error = f"{annotation} method cannot define parameters"
|
expected_error = f"{annotation} methods cannot define parameters"
|
||||||
self.expect_failure(block, expected_error)
|
self.expect_failure(block, expected_error)
|
||||||
|
|
||||||
def test_setter_docstring(self):
|
def test_setter_docstring(self):
|
||||||
|
@ -2655,7 +2655,6 @@ class ClinicExternalTest(TestCase):
|
||||||
bool()
|
bool()
|
||||||
double()
|
double()
|
||||||
float()
|
float()
|
||||||
init()
|
|
||||||
int()
|
int()
|
||||||
long()
|
long()
|
||||||
Py_ssize_t()
|
Py_ssize_t()
|
||||||
|
@ -3945,7 +3944,7 @@ class ClinicReprTests(unittest.TestCase):
|
||||||
cls=None,
|
cls=None,
|
||||||
c_basename=None,
|
c_basename=None,
|
||||||
full_name='foofoo',
|
full_name='foofoo',
|
||||||
return_converter=clinic.init_return_converter(),
|
return_converter=clinic.int_return_converter(),
|
||||||
kind=clinic.FunctionKind.METHOD_INIT,
|
kind=clinic.FunctionKind.METHOD_INIT,
|
||||||
coexist=False
|
coexist=False
|
||||||
)
|
)
|
||||||
|
|
|
@ -859,9 +859,6 @@ class CLanguage(Language):
|
||||||
limited_capi = False
|
limited_capi = False
|
||||||
|
|
||||||
parsearg: str | None
|
parsearg: str | None
|
||||||
if f.kind in {GETTER, SETTER} and parameters:
|
|
||||||
fail(f"@{f.kind.name.lower()} method cannot define parameters")
|
|
||||||
|
|
||||||
if not parameters:
|
if not parameters:
|
||||||
parser_code: list[str] | None
|
parser_code: list[str] | None
|
||||||
if f.kind is GETTER:
|
if f.kind is GETTER:
|
||||||
|
@ -1615,12 +1612,9 @@ class CLanguage(Language):
|
||||||
for converter in converters:
|
for converter in converters:
|
||||||
converter.set_template_dict(template_dict)
|
converter.set_template_dict(template_dict)
|
||||||
|
|
||||||
f.return_converter.render(f, data)
|
if f.kind not in {SETTER, METHOD_INIT}:
|
||||||
if f.kind is SETTER:
|
f.return_converter.render(f, data)
|
||||||
# All setters return an int.
|
template_dict['impl_return_type'] = f.return_converter.type
|
||||||
template_dict['impl_return_type'] = 'int'
|
|
||||||
else:
|
|
||||||
template_dict['impl_return_type'] = f.return_converter.type
|
|
||||||
|
|
||||||
template_dict['declarations'] = libclinic.format_escape("\n".join(data.declarations))
|
template_dict['declarations'] = libclinic.format_escape("\n".join(data.declarations))
|
||||||
template_dict['initializers'] = "\n\n".join(data.initializers)
|
template_dict['initializers'] = "\n\n".join(data.initializers)
|
||||||
|
@ -4565,20 +4559,6 @@ class int_return_converter(long_return_converter):
|
||||||
cast = '(long)'
|
cast = '(long)'
|
||||||
|
|
||||||
|
|
||||||
class init_return_converter(long_return_converter):
|
|
||||||
"""
|
|
||||||
Special return converter for __init__ functions.
|
|
||||||
"""
|
|
||||||
type = 'int'
|
|
||||||
cast = '(long)'
|
|
||||||
|
|
||||||
def render(
|
|
||||||
self,
|
|
||||||
function: Function,
|
|
||||||
data: CRenderData
|
|
||||||
) -> None: ...
|
|
||||||
|
|
||||||
|
|
||||||
class unsigned_long_return_converter(long_return_converter):
|
class unsigned_long_return_converter(long_return_converter):
|
||||||
type = 'unsigned long'
|
type = 'unsigned long'
|
||||||
conversion_fn = 'PyLong_FromUnsignedLong'
|
conversion_fn = 'PyLong_FromUnsignedLong'
|
||||||
|
@ -5111,8 +5091,8 @@ class DSLParser:
|
||||||
except ValueError:
|
except ValueError:
|
||||||
fail(f"Badly formed annotation for {full_name!r}: {forced_converter!r}")
|
fail(f"Badly formed annotation for {full_name!r}: {forced_converter!r}")
|
||||||
|
|
||||||
if self.kind is METHOD_INIT:
|
if self.kind in {METHOD_INIT, SETTER}:
|
||||||
return init_return_converter()
|
return int_return_converter()
|
||||||
return CReturnConverter()
|
return CReturnConverter()
|
||||||
|
|
||||||
def parse_cloned_function(self, names: FunctionNames, existing: str) -> None:
|
def parse_cloned_function(self, names: FunctionNames, existing: str) -> None:
|
||||||
|
@ -5294,6 +5274,11 @@ class DSLParser:
|
||||||
if not self.indent.infer(line):
|
if not self.indent.infer(line):
|
||||||
return self.next(self.state_function_docstring, line)
|
return self.next(self.state_function_docstring, line)
|
||||||
|
|
||||||
|
assert self.function is not None
|
||||||
|
if self.function.kind in {GETTER, SETTER}:
|
||||||
|
getset = self.function.kind.name.lower()
|
||||||
|
fail(f"@{getset} methods cannot define parameters")
|
||||||
|
|
||||||
self.parameter_continuation = ''
|
self.parameter_continuation = ''
|
||||||
return self.next(self.state_parameter, line)
|
return self.next(self.state_parameter, line)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue