From 7cbfd751490e54743c6e3324b96bb1b0ce7cae75 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 16 Jul 2023 21:40:37 +0200 Subject: [PATCH 1/2] gh-104050: Improve Argument Clinic type annotation coverage Add various missing annotations in the following classes: - BlockPrinter - CConverter - CLanguage - FormatCounterFormatter - Language - _TextAccumulator --- Tools/clinic/clinic.py | 50 +++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 861a6507eae753..c3a82e322041a2 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -108,7 +108,7 @@ class _TextAccumulator(NamedTuple): def _text_accumulator() -> _TextAccumulator: text: list[str] = [] - def output(): + def output() -> str: s = ''.join(text) text.clear() return s @@ -432,10 +432,11 @@ class FormatCounterFormatter(string.Formatter): the counts dict would now look like {'a': 2, 'b': 1, 'c': 1} """ - def __init__(self): - self.counts = collections.Counter() + def __init__(self) -> None: + self.counts: dict[str, int] = collections.Counter() - def get_value(self, key, args, kwargs): + def get_value(self, key: str | int, args, kwargs) -> str: + assert isinstance(key, str) self.counts[key] += 1 return '' @@ -446,18 +447,25 @@ class Language(metaclass=abc.ABCMeta): stop_line = "" checksum_line = "" - def __init__(self, filename): + def __init__(self, filename: str) -> None: pass @abc.abstractmethod - def render(self, clinic, signatures): + def render( + self, + clinic: Clinic | None, + signatures: Iterable[Module | Class | Function] + ) -> str: pass - def parse_line(self, line): + def parse_line(self, line: str) -> None: pass - def validate(self): - def assert_only_one(attr, *additional_fields): + def validate(self) -> None: + def assert_only_one( + attr: str, + *additional_fields: str + ) -> None: """ Ensures that the string found at getattr(self, attr) contains exactly one formatter replacement string for @@ -484,10 +492,10 @@ def assert_only_one(attr, *additional_fields): """ fields = ['dsl_name'] fields.extend(additional_fields) - line = getattr(self, attr) + line: str = getattr(self, attr) fcf = FormatCounterFormatter() fcf.format(line) - def local_fail(should_be_there_but_isnt): + def local_fail(should_be_there_but_isnt: bool) -> None: if should_be_there_but_isnt: fail("{} {} must contain {{{}}} exactly once!".format( self.__class__.__name__, attr, name)) @@ -748,10 +756,10 @@ class CLanguage(Language): stop_line = "[{dsl_name} start generated code]*/" checksum_line = "/*[{dsl_name} end generated code: {arguments}]*/" - def __init__(self, filename): + def __init__(self, filename: str) -> None: super().__init__(filename) self.cpp = cpp.Monitor(filename) - self.cpp.fail = fail + setattr(self.cpp, "fail", fail) def parse_line(self, line: str) -> None: self.cpp.writeline(line) @@ -934,6 +942,7 @@ def parser_body( add(field) return linear_format(output(), parser_declarations=declarations) + parsearg: str | None if not parameters: parser_code: list[str] | None if not requires_defining_class: @@ -1879,7 +1888,12 @@ class BlockPrinter: language: Language f: io.StringIO = dc.field(default_factory=io.StringIO) - def print_block(self, block, *, core_includes=False): + def print_block( + self, + block: Block, + *, + core_includes: bool = False + ) -> None: input = block.input output = block.output dsl_name = block.dsl_name @@ -1930,7 +1944,7 @@ def print_block(self, block, *, core_includes=False): write(self.language.checksum_line.format(dsl_name=dsl_name, arguments=arguments)) write("\n") - def write(self, text): + def write(self, text: str) -> None: self.f.write(text) @@ -2749,7 +2763,7 @@ class CConverter(metaclass=CConverterAutoRegister): # If not None, should be a string representing a pointer to a # PyTypeObject (e.g. "&PyUnicode_Type"). # Only used by the 'O!' format unit (and the "object" converter). - subclass_of = None + subclass_of: str | None = None # Do we want an adjacent '_length' variable for this variable? # Only used by format units ending with '#'. @@ -2942,7 +2956,7 @@ def simple_declaration(self, by_reference=False, *, in_parser=False): prototype.append(name) return "".join(prototype) - def declaration(self, *, in_parser=False): + def declaration(self, *, in_parser=False) -> str: """ The C statement to declare this variable. """ @@ -3000,7 +3014,7 @@ def pre_render(self): """ pass - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str): if self.format_unit == 'O&': return """ if (!{converter}({argname}, &{paramname})) {{{{ From 03f8031cf37ca1e2dc8f5448bf5b1736950521ab Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 17 Jul 2023 01:23:46 +0200 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Alex Waygood --- 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 c3a82e322041a2..dfde73b847a992 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -433,10 +433,9 @@ class FormatCounterFormatter(string.Formatter): {'a': 2, 'b': 1, 'c': 1} """ def __init__(self) -> None: - self.counts: dict[str, int] = collections.Counter() + self.counts = collections.Counter[str]() - def get_value(self, key: str | int, args, kwargs) -> str: - assert isinstance(key, str) + def get_value(self, key: str, args, kwargs) -> str: # type: ignore[override] self.counts[key] += 1 return '' @@ -759,7 +758,7 @@ class CLanguage(Language): def __init__(self, filename: str) -> None: super().__init__(filename) self.cpp = cpp.Monitor(filename) - setattr(self.cpp, "fail", fail) + self.cpp.fail = fail # type: ignore[method-assign] def parse_line(self, line: str) -> None: self.cpp.writeline(line)