Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-104050: Annotate toplevel functions in clinic.py #106435

Merged
Merged
63 changes: 47 additions & 16 deletions Tools/clinic/clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ def permute_optional_groups(left, required, right):
return tuple(accumulator)


def strip_leading_and_trailing_blank_lines(s):
def strip_leading_and_trailing_blank_lines(s: str) -> str:
lines = s.rstrip().split('\n')
while lines:
line = lines[0]
Expand All @@ -585,7 +585,11 @@ def strip_leading_and_trailing_blank_lines(s):
return '\n'.join(lines)

@functools.lru_cache()
def normalize_snippet(s, *, indent=0):
def normalize_snippet(
s: str,
*,
indent: int = 0
) -> str:
"""
Reformats s:
* removes leading and trailing blank lines
Expand All @@ -599,7 +603,11 @@ def normalize_snippet(s, *, indent=0):
return s


def declare_parser(f, *, hasformat=False):
def declare_parser(
f: Function,
*,
hasformat: bool = False
) -> str:
"""
Generates the code template for a static local PyArg_Parser variable,
with an initializer. For core code (incl. builtin modules) the
Expand Down Expand Up @@ -658,7 +666,10 @@ def declare_parser(f, *, hasformat=False):
return normalize_snippet(declarations)


def wrap_declarations(text, length=78):
def wrap_declarations(
text: str,
length: int = 78
) -> str:
"""
A simple-minded text wrapper for C function declarations.

Expand All @@ -680,14 +691,14 @@ def wrap_declarations(text, length=78):
if not after_l_paren:
lines.append(line)
continue
parameters, _, after_r_paren = after_l_paren.partition(')')
in_paren, _, after_r_paren = after_l_paren.partition(')')
if not _:
lines.append(line)
continue
if ',' not in parameters:
if ',' not in in_paren:
lines.append(line)
continue
parameters = [x.strip() + ", " for x in parameters.split(',')]
parameters = [x.strip() + ", " for x in in_paren.split(',')]
prefix += "("
if len(prefix) < length:
spaces = " " * len(prefix)
Expand Down Expand Up @@ -1589,7 +1600,12 @@ def OverrideStdioWith(stdout):
sys.stdout = saved_stdout


def create_regex(before, after, word=True, whole_line=True):
def create_regex(
before: str,
after: str,
word: bool = True,
whole_line: bool = True
) -> re.Pattern[str]:
"""Create an re object for matching marker lines."""
group_re = r"\w+" if word else ".+"
pattern = r'{}({}){}'
Expand Down Expand Up @@ -1985,7 +2001,7 @@ def file_changed(filename: str, new_contents: str) -> bool:
return True


def write_file(filename: str, new_contents: str):
def write_file(filename: str, new_contents: str) -> None:
# Atomic write using a temporary file and os.replace()
filename_new = f"{filename}.new"
with open(filename_new, "w", encoding="utf-8") as fp:
Expand Down Expand Up @@ -2602,7 +2618,10 @@ def __getattribute__(self, name: str):
fail("Stepped on a land mine, trying to access attribute " + repr(name) + ":\n" + self.__message__)


def add_c_converter(f, name=None):
def add_c_converter(
f: type[CConverter],
name: str | None = None
) -> type[CConverter]:
if not name:
name = f.__name__
if not name.endswith('_converter'):
Expand All @@ -2620,7 +2639,10 @@ def add_default_legacy_c_converter(cls):
legacy_converters[cls.format_unit] = cls
return cls

def add_legacy_c_converter(format_unit, **kwargs):
def add_legacy_c_converter(
format_unit: str,
**kwargs
) -> Callable[[ConverterType], ConverterType]:
"""
Adds a legacy converter.
"""
Expand Down Expand Up @@ -3887,7 +3909,9 @@ def parse_arg(self, argname: str, displayname: str) -> str:
return super().parse_arg(argname, displayname)


def correct_name_for_self(f) -> tuple[str, str]:
def correct_name_for_self(
f: Function
) -> tuple[str, str]:
if f.kind in (CALLABLE, METHOD_INIT):
if f.cls:
return "PyObject *", "self"
Expand All @@ -3898,7 +3922,9 @@ def correct_name_for_self(f) -> tuple[str, str]:
return "PyTypeObject *", "type"
raise RuntimeError("Unhandled type of function f: " + repr(f.kind))

def required_type_for_self_for_parser(f):
def required_type_for_self_for_parser(
f: Function
) -> str | None:
type, _ = correct_name_for_self(f)
if f.kind in (METHOD_INIT, METHOD_NEW, STATIC_METHOD, CLASS_METHOD):
return type
Expand Down Expand Up @@ -4193,7 +4219,12 @@ class float_return_converter(double_return_converter):
cast = '(double)'


def eval_ast_expr(node, globals, *, filename='-'):
def eval_ast_expr(
node: ast.expr,
globals: dict[str, Any],
*,
filename: str = '-'
) -> FunctionType:
"""
Takes an ast.Expr node. Compiles and evaluates it.
Returns the result of the expression.
Expand All @@ -4205,8 +4236,8 @@ def eval_ast_expr(node, globals, *, filename='-'):
if isinstance(node, ast.Expr):
node = node.value

node = ast.Expression(node)
co = compile(node, filename, 'eval')
expr = ast.Expression(node)
co = compile(expr, filename, 'eval')
fn = FunctionType(co, globals)
return fn()

Expand Down