From 5b1446983541bd08e03d1eda91df87d78e05440a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 12 Feb 2024 23:10:35 +0100 Subject: [PATCH 1/3] gh-113317, Argument Clinic: Add Clinic.fail() method * Add Clinic.fail() and Clinic.warn() methods. * Language.render(): clinic argument is now mandatory (fix type hint). * Replace some fail() and warn() calls with Clinic.fail() and Clinic.warn(). --- Tools/clinic/clinic.py | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index db57d17899af93..54a9460c6b92f7 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -282,7 +282,7 @@ def __init__(self, filename: str) -> None: @abc.abstractmethod def render( self, - clinic: Clinic | None, + clinic: Clinic, signatures: Iterable[Module | Class | Function] ) -> str: ... @@ -635,14 +635,16 @@ def parse_line(self, line: str) -> None: def render( self, - clinic: Clinic | None, + clinic: Clinic, signatures: Iterable[Module | Class | Function] ) -> str: function = None for o in signatures: if isinstance(o, Function): - if function: - fail("You may specify at most one function per block.\nFound a block containing at least two:\n\t" + repr(function) + " and " + repr(o)) + if function is not None: + clinic.fail("You may specify at most one function per block.\n" + "Found a block containing at least two:\n" + "\t" + repr(function) + " and " + repr(o)) function = o return self.render_function(clinic, function) @@ -834,7 +836,7 @@ def output_templates( min_kw_only = i - max_pos elif p.is_vararg(): if vararg != self.NO_VARARG: - fail("Too many var args") + clinic.fail("Too many var args") pseudo_args += 1 vararg = i - 1 else: @@ -877,7 +879,7 @@ def output_templates( docstring_prototype = docstring_definition = '' elif f.kind is SETTER: if f.docstring: - fail("docstrings are only supported for @getter, not @setter") + clinic.fail("docstrings are only supported for @getter, not @setter") return_value_declaration = "int {return_value};" methoddef_define = self.SETTERDEF_PROTOTYPE_DEFINE docstring_prototype = docstring_definition = '' @@ -930,12 +932,12 @@ def parser_body( (any(p.is_optional() for p in parameters) and any(p.is_keyword_only() and not p.is_optional() for p in parameters)) or any(c.broken_limited_capi for c in converters)): - warn(f"Function {f.full_name} cannot use limited C API") + clinic.warn(f"Function {f.full_name} cannot use limited C API") limited_capi = False parsearg: str | None if f.kind in {GETTER, SETTER} and parameters: - fail(f"@{f.kind.name.lower()} method cannot define parameters") + clinic.fail(f"@{f.kind.name.lower()} method cannot define parameters") if not parameters: parser_code: list[str] | None @@ -1652,8 +1654,8 @@ def render_function( c.render(p, data) if has_option_groups and (not positional): - fail("You cannot use optional groups ('[' and ']') " - "unless all parameters are positional-only ('/').") + clinic.fail("You cannot use optional groups ('[' and ']') " + "unless all parameters are positional-only ('/').") # HACK # when we're METH_O, but have a custom return converter, @@ -2350,6 +2352,19 @@ def __init__( global clinic clinic = self + def warn(self, *args: object) -> None: + warn_or_fail(*args, + filename=self.filename, + line_number=self.block_parser.line_number, + fail=False) + + def fail(self, *args: object, line_number: int | None = None) -> NoReturn: + if line_number is None: + line_number = self.block_parser.line_number + warn_or_fail(*args, + filename=self.filename, line_number=line_number, + fail=True) + def add_include(self, name: str, reason: str, *, condition: str | None = None) -> None: try: @@ -2418,7 +2433,7 @@ def parse(self, input: str) -> str: if destination.type == 'buffer': block.input = "dump " + name + "\n" - warn("Destination buffer " + repr(name) + " not empty at end of file, emptying.") + self.warn("Destination buffer " + repr(name) + " not empty at end of file, emptying.") printer.write("\n") printer.print_block(block, limited_capi=self.limited_capi, From fa9bc964eaafd6414a2defffade30545420988a5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 14 Feb 2024 22:59:09 +0100 Subject: [PATCH 2/3] Update Tools/clinic/clinic.py Co-authored-by: Erlend E. Aasland --- Tools/clinic/clinic.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 54a9460c6b92f7..7a0175616978cf 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -2353,10 +2353,9 @@ def __init__( clinic = self def warn(self, *args: object) -> None: - warn_or_fail(*args, - filename=self.filename, - line_number=self.block_parser.line_number, - fail=False) + warn(*args, + filename=self.filename, + line_number=self.block_parser.line_number) def fail(self, *args: object, line_number: int | None = None) -> NoReturn: if line_number is None: From 185f28479658b36b66a878633681330004190d52 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 14 Feb 2024 22:59:19 +0100 Subject: [PATCH 3/3] Update Tools/clinic/clinic.py Co-authored-by: Erlend E. Aasland --- Tools/clinic/clinic.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 7a0175616978cf..aa078edf5753ef 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -2360,9 +2360,8 @@ def warn(self, *args: object) -> None: def fail(self, *args: object, line_number: int | None = None) -> NoReturn: if line_number is None: line_number = self.block_parser.line_number - warn_or_fail(*args, - filename=self.filename, line_number=line_number, - fail=True) + fail(*args, + filename=self.filename, line_number=line_number) def add_include(self, name: str, reason: str, *, condition: str | None = None) -> None: