Skip to content

Commit

Permalink
pythongh-106970: Fix Argument Clinic 'destination <name> clear' comma…
Browse files Browse the repository at this point in the history
…nd (pythonGH-106972)

Add test for the 'destination <name> clear' command,
and the 'destination' directive in general.

Fix two bugs in 'destination <name> clear' command:

1. The text attribute of the allocator is called 'text', not '_text'
2. Return after processing the 'clear' command,
   instead of proceeding directly to the fail().
(cherry picked from commit 3372bcb)

Co-authored-by: Erlend E. Aasland <erlend@python.org>
  • Loading branch information
erlend-aasland authored and miss-islington committed Jul 22, 2023
1 parent d0176ed commit 588f331
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 8 deletions.
56 changes: 56 additions & 0 deletions Lib/test/clinic.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -4954,3 +4954,59 @@ Test_meth_coexist(TestObj *self, PyObject *Py_UNUSED(ignored))
static PyObject *
Test_meth_coexist_impl(TestObj *self)
/*[clinic end generated code: output=808a293d0cd27439 input=2a1d75b5e6fec6dd]*/


/*[clinic input]
output push
output preset buffer
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5bff3376ee0df0b5]*/

/*[clinic input]
buffer_clear
a: int
We'll call 'destination buffer clear' after this.
Argument Clinic's buffer preset puts most generated code into the
'buffer' destination, except from 'impl_definition', which is put into
the 'block' destination, so we should expect everything but
'impl_definition' to be cleared.
[clinic start generated code]*/

static PyObject *
buffer_clear_impl(PyObject *module, int a)
/*[clinic end generated code: output=f14bba74677e1846 input=a4c308a6fdab043c]*/

/*[clinic input]
destination buffer clear
output pop
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f20d06adb8252084]*/


/*[clinic input]
output push
destination test1 new buffer
output everything suppress
output docstring_definition test1
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5a77c454970992fc]*/

/*[clinic input]
new_dest
a: int
Only this docstring should be outputted to test1.
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=da5af421ed8996ed]*/

/*[clinic input]
dump test1
output pop
[clinic start generated code]*/

PyDoc_STRVAR(new_dest__doc__,
"new_dest($module, /, a)\n"
"--\n"
"\n"
"Only this docstring should be outputted to test1.");
/*[clinic end generated code: output=9cac703f51d90e84 input=090db8df4945576d]*/
9 changes: 9 additions & 0 deletions Lib/test/test_clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,15 @@ def test_cpp_monitor_fail_no_matching_if(self):
out = self.expect_failure(raw)
self.assertEqual(out, msg)

def test_unknown_destination_command(self):
out = self.expect_failure("""
/*[clinic input]
destination buffer nosuchcommand
[clinic start generated code]*/
""")
msg = "unknown destination command 'nosuchcommand'"
self.assertIn(msg, out)


class ClinicGroupPermuterTest(TestCase):
def _test(self, l, m, r, output):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fix bugs in the Argument Clinic ``destination <name> clear`` command; the
destination buffers would never be cleared, and the ``destination``
directive parser would simply continue to the fault handler after processing
the command. Patch by Erlend E. Aasland.
16 changes: 8 additions & 8 deletions Tools/clinic/clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1906,7 +1906,7 @@ def __getitem__(self, i):

def clear(self):
for ta in self._array:
ta._text.clear()
ta.text.clear()

def dump(self):
texts = [ta.output() for ta in self._array]
Expand Down Expand Up @@ -4366,13 +4366,13 @@ def directive_destination(
command: str,
*args
) -> None:
if command == 'new':
self.clinic.add_destination(name, *args)
return

if command == 'clear':
self.clinic.get_destination(name).clear()
fail("unknown destination command", repr(command))
match command:
case "new":
self.clinic.add_destination(name, *args)
case "clear":
self.clinic.get_destination(name).clear()
case _:
fail("unknown destination command", repr(command))


def directive_output(
Expand Down

0 comments on commit 588f331

Please sign in to comment.