gh-113317: Argument Clinic: don't use global state in warn() and fail() (#115510)

This commit is contained in:
Erlend E. Aasland 2024-02-15 13:22:21 +01:00 committed by GitHub
parent 98ee4ecdbc
commit 7f074a771b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 23 additions and 16 deletions

View file

@ -1900,7 +1900,7 @@ def test_parameters_no_more_than_one_vararg(self):
*vararg1: object
*vararg2: object
"""
self.expect_failure(block, err, lineno=0)
self.expect_failure(block, err, lineno=3)
def test_function_not_at_column_0(self):
function = self.parse_function("""
@ -2286,10 +2286,10 @@ def test_non_ascii_character_in_docstring(self):
self.parse(block)
# The line numbers are off; this is a known limitation.
expected = dedent("""\
Warning in file 'clinic_tests' on line 0:
Warning:
Non-ascii characters are not allowed in docstrings: 'á'
Warning in file 'clinic_tests' on line 0:
Warning:
Non-ascii characters are not allowed in docstrings: 'ü', 'á', 'ß'
""")
@ -2390,7 +2390,7 @@ def test_state_func_docstring_no_summary(self):
docstring1
docstring2
"""
self.expect_failure(block, err, lineno=0)
self.expect_failure(block, err, lineno=3)
def test_state_func_docstring_only_one_param_template(self):
err = "You may not specify {parameters} more than once in a docstring!"
@ -2404,7 +2404,7 @@ def test_state_func_docstring_only_one_param_template(self):
these are the params again:
{parameters}
"""
self.expect_failure(block, err, lineno=0)
self.expect_failure(block, err, lineno=7)
class ClinicExternalTest(TestCase):

View file

@ -116,11 +116,6 @@ def warn_or_fail(
line_number: int | None = None,
) -> None:
joined = " ".join([str(a) for a in args])
if clinic:
if filename is None:
filename = clinic.filename
if getattr(clinic, 'block_parser', None) and (line_number is None):
line_number = clinic.block_parser.line_number
error = ClinicError(joined, filename=filename, lineno=line_number)
if fail:
raise error
@ -277,7 +272,7 @@ class Language(metaclass=abc.ABCMeta):
checksum_line = ""
def __init__(self, filename: str) -> None:
...
self.filename = filename
@abc.abstractmethod
def render(
@ -833,8 +828,6 @@ def output_templates(
if not p.is_optional():
min_kw_only = i - max_pos
elif p.is_vararg():
if vararg != self.NO_VARARG:
fail("Too many var args")
pseudo_args += 1
vararg = i - 1
else:
@ -1889,7 +1882,12 @@ def __next__(self) -> Block:
raise StopIteration
if self.dsl_name:
return_value = self.parse_clinic_block(self.dsl_name)
try:
return_value = self.parse_clinic_block(self.dsl_name)
except ClinicError as exc:
exc.filename = self.language.filename
exc.lineno = self.line_number
raise
self.dsl_name = None
self.first_block = False
return return_value
@ -5071,6 +5069,7 @@ def parse(self, block: Block) -> None:
self.state(line)
except ClinicError as exc:
exc.lineno = line_number
exc.filename = self.clinic.filename
raise
self.do_post_block_processing_cleanup(line_number)
@ -5078,7 +5077,8 @@ def parse(self, block: Block) -> None:
if self.preserve_output:
if block.output:
fail("'preserve' only works for blocks that don't produce any output!")
fail("'preserve' only works for blocks that don't produce any output!",
line_number=line_number)
block.output = self.saved_output
def in_docstring(self) -> bool:
@ -5503,6 +5503,8 @@ def parse_parameter(self, line: str) -> None:
f"invalid parameter declaration (**kwargs?): {line!r}")
if function_args.vararg:
if any(p.is_vararg() for p in self.function.parameters.values()):
fail("Too many var args")
is_vararg = True
parameter = function_args.vararg
else:
@ -6174,7 +6176,12 @@ def do_post_block_processing_cleanup(self, lineno: int) -> None:
return
self.check_remaining_star(lineno)
self.function.docstring = self.format_docstring()
try:
self.function.docstring = self.format_docstring()
except ClinicError as exc:
exc.lineno = lineno
exc.filename = self.clinic.filename
raise