From fa43e47dd8a5d35272cf6cbddeb279b995072b0a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 3 Jul 2023 23:08:55 +0200 Subject: [PATCH 1/2] Annotate Argument Clinic DSLParser.state_parameter() --- Tools/clinic/clinic.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 41d4274fc744e0..b5b955bbf1737c 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -4764,14 +4764,16 @@ def to_required(self): for p in self.function.parameters.values(): p.group = -p.group - def state_parameter(self, line): - if self.parameter_continuation: - line = self.parameter_continuation + ' ' + line.lstrip() - self.parameter_continuation = '' + def state_parameter(self, line: str | None) -> None: + assert isinstance(self.function, Function) if not self.valid_line(line): return + if self.parameter_continuation: + line = self.parameter_continuation + ' ' + line.lstrip() + self.parameter_continuation = '' + assert self.indent.depth == 2 indent = self.indent.infer(line) if indent == -1: @@ -4821,6 +4823,7 @@ def state_parameter(self, line): fields[0] = name line = ' '.join(fields) + default: str | None base, equals, default = line.rpartition('=') if not equals: base = default @@ -4865,6 +4868,7 @@ def state_parameter(self, line): if not default: if self.parameter_state == self.ps_optional: fail("Can't have a parameter without a default (" + repr(parameter_name) + ")\nafter a parameter with a default!") + value: Sentinels | Null if is_vararg: value = NULL kwargs.setdefault('c_default', "NULL") @@ -4929,6 +4933,7 @@ def bad_node(self, node): expr = module.body[0].value # mild hack: explicitly support NULL as a default value + c_default: str | None if isinstance(expr, ast.Name) and expr.id == 'NULL': value = NULL py_default = '' @@ -4945,7 +4950,7 @@ def bad_node(self, node): value = unknown elif isinstance(expr, ast.Attribute): a = [] - n = expr + n: ast.expr | ast.Attribute = expr while isinstance(n, ast.Attribute): a.append(n.attr) n = n.value @@ -4992,6 +4997,7 @@ def bad_node(self, node): # but the parameter object gets the python name converter = dict[name](c_name or parameter_name, parameter_name, self.function, value, **kwargs) + kind: inspect._ParameterKind if is_vararg: kind = inspect.Parameter.VAR_POSITIONAL elif self.keyword_only: @@ -5103,7 +5109,7 @@ def parse_special_symbol(self, symbol): fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.") p.kind = inspect.Parameter.POSITIONAL_ONLY - def state_parameter_docstring_start(self, line: str) -> None: + def state_parameter_docstring_start(self, line: str | None) -> None: self.parameter_docstring_indent = len(self.indent.margin) assert self.indent.depth == 3 return self.next(self.state_parameter_docstring, line) From 73c1dc2ba9c8e01078b5c2361fc24e59f83816f2 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 3 Jul 2023 23:41:45 +0200 Subject: [PATCH 2/2] Fix the remaining stuff --- Tools/clinic/clinic.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index e4a884e1fba9c3..a07fcbd8cabf76 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -4864,7 +4864,9 @@ def state_parameter(self, line: str | None) -> None: if not module: fail("Function " + self.function.name + " has an invalid parameter declaration:\n\t" + line) - function_args = module.body[0].args + function = module.body[0] + assert isinstance(function, ast.FunctionDef) + function_args = function.args if len(function_args.args) > 1: fail("Function " + self.function.name + " has an invalid parameter declaration (comma?):\n\t" + line) @@ -4950,7 +4952,9 @@ def bad_node(self, node): if bad: fail("Unsupported expression as default value: " + repr(default)) - expr = module.body[0].value + assignment = module.body[0] + assert isinstance(assignment, ast.Assign) + expr = assignment.value # mild hack: explicitly support NULL as a default value c_default: str | None if isinstance(expr, ast.Name) and expr.id == 'NULL': @@ -4989,7 +4993,7 @@ def bad_node(self, node): else: value = ast.literal_eval(expr) py_default = repr(value) - if isinstance(value, (bool, None.__class__)): + if isinstance(value, (bool, NoneType)): c_default = "Py_" + py_default elif isinstance(value, str): c_default = c_repr(value)