Skip to content

gh-113317, Argument Clinic: Add Clinic.fail() method #115371

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

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions Tools/clinic/clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
...
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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 = ''
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -2350,6 +2352,17 @@ def __init__(
global clinic
clinic = self

def warn(self, *args: object) -> None:
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:
line_number = self.block_parser.line_number
fail(*args,
filename=self.filename, line_number=line_number)

def add_include(self, name: str, reason: str,
*, condition: str | None = None) -> None:
try:
Expand Down Expand Up @@ -2418,7 +2431,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,
Expand Down