summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlend E. Aasland <erlend.aasland@protonmail.com>2023-05-12 08:34:00 (GMT)
committerGitHub <noreply@github.com>2023-05-12 08:34:00 (GMT)
commitb2c1b4da1935639cb89fbbad0ce170a1182537bd (patch)
tree5b68de40c8c0aa71db3157e0653450206d6beb13
parent15795b57d92ee6315b5c8263290944b16834b5f2 (diff)
downloadcpython-b2c1b4da1935639cb89fbbad0ce170a1182537bd.zip
cpython-b2c1b4da1935639cb89fbbad0ce170a1182537bd.tar.gz
cpython-b2c1b4da1935639cb89fbbad0ce170a1182537bd.tar.bz2
gh-104389: Add 'unused' keyword to Argument Clinic C converters (#104390)
Use the unused keyword param in the converter to explicitly mark an argument as unused: /*[clinic input] SomeBaseClass.stubmethod flag: bool(unused=True) [clinic start generated code]*/
-rw-r--r--Doc/howto/clinic.rst3
-rw-r--r--Lib/test/test_clinic.py38
-rw-r--r--Misc/NEWS.d/next/Tools-Demos/2023-05-11-15-12-11.gh-issue-104389.EiOhB3.rst2
-rwxr-xr-xTools/clinic/clinic.py20
4 files changed, 62 insertions, 1 deletions
diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst
index 6ebc2d9..4620b46 100644
--- a/Doc/howto/clinic.rst
+++ b/Doc/howto/clinic.rst
@@ -775,6 +775,9 @@ All Argument Clinic converters accept the following arguments:
because :pep:`8` mandates that the Python library may not use
annotations.
+ ``unused``
+ Wrap the argument with :c:macro:`Py_UNUSED` in the impl function signature.
+
In addition, some converters accept additional arguments. Here is a list
of these arguments, along with their meanings:
diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py
index 6aaf4d1..28d9f65 100644
--- a/Lib/test/test_clinic.py
+++ b/Lib/test/test_clinic.py
@@ -774,6 +774,44 @@ Not at column 0!
module, function = block.signatures
self.assertIsInstance((function.parameters['path']).converter, clinic.str_converter)
+ def test_unused_param(self):
+ block = self.parse("""
+ module foo
+ foo.func
+ fn: object
+ k: float
+ i: float(unused=True)
+ /
+ *
+ flag: bool(unused=True) = False
+ """)
+ sig = block.signatures[1] # Function index == 1
+ params = sig.parameters
+ conv = lambda fn: params[fn].converter
+ dataset = (
+ {"name": "fn", "unused": False},
+ {"name": "k", "unused": False},
+ {"name": "i", "unused": True},
+ {"name": "flag", "unused": True},
+ )
+ for param in dataset:
+ name, unused = param.values()
+ with self.subTest(name=name, unused=unused):
+ p = conv(name)
+ # Verify that the unused flag is parsed correctly.
+ self.assertEqual(unused, p.unused)
+
+ # Now, check that we'll produce correct code.
+ decl = p.simple_declaration(in_parser=False)
+ if unused:
+ self.assertIn("Py_UNUSED", decl)
+ else:
+ self.assertNotIn("Py_UNUSED", decl)
+
+ # Make sure the Py_UNUSED macro is not used in the parser body.
+ parser_decl = p.simple_declaration(in_parser=True)
+ self.assertNotIn("Py_UNUSED", parser_decl)
+
def parse(self, text):
c = FakeClinic()
parser = DSLParser(c)
diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-05-11-15-12-11.gh-issue-104389.EiOhB3.rst b/Misc/NEWS.d/next/Tools-Demos/2023-05-11-15-12-11.gh-issue-104389.EiOhB3.rst
new file mode 100644
index 0000000..854e1cc
--- /dev/null
+++ b/Misc/NEWS.d/next/Tools-Demos/2023-05-11-15-12-11.gh-issue-104389.EiOhB3.rst
@@ -0,0 +1,2 @@
+Argument Clinic C converters now accept the ``unused`` keyword, for wrapping
+a parameter with :c:macro:`Py_UNUSED`. Patch by Erlend E. Aasland.
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
index 2ae8a02..19c4cd2 100755
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -2599,6 +2599,9 @@ class CConverter(metaclass=CConverterAutoRegister):
# Every non-abstract subclass should supply a valid value.
c_ignored_default = 'NULL'
+ # If true, wrap with Py_UNUSED.
+ unused = False
+
# The C converter *function* to be used, if any.
# (If this is not None, format_unit must be 'O&'.)
converter = None
@@ -2651,9 +2654,22 @@ class CConverter(metaclass=CConverterAutoRegister):
signature_name = None
# keep in sync with self_converter.__init__!
- def __init__(self, name, py_name, function, default=unspecified, *, c_default=None, py_default=None, annotation=unspecified, **kwargs):
+ def __init__(self,
+ # Positional args:
+ name,
+ py_name,
+ function,
+ default=unspecified,
+ *, # Keyword only args:
+ c_default=None,
+ py_default=None,
+ annotation=unspecified,
+ unused=False,
+ **kwargs
+ ):
self.name = ensure_legal_c_identifier(name)
self.py_name = py_name
+ self.unused = unused
if default is not unspecified:
if self.default_type and not isinstance(default, (self.default_type, Unknown)):
@@ -2800,6 +2816,8 @@ class CConverter(metaclass=CConverterAutoRegister):
name = self.parser_name
else:
name = self.name
+ if self.unused:
+ name = f"Py_UNUSED({name})"
prototype.append(name)
return "".join(prototype)