Skip to content

Commit

Permalink
gh-104389: Add 'unused' keyword to Argument Clinic C converters (#104390
Browse files Browse the repository at this point in the history
)

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]*/
  • Loading branch information
erlend-aasland authored May 12, 2023
1 parent 15795b5 commit b2c1b4d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Doc/howto/clinic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
38 changes: 38 additions & 0 deletions Lib/test/test_clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,44 @@ def test_legacy_converters(self):
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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
20 changes: 19 additions & 1 deletion Tools/clinic/clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)):
Expand Down Expand Up @@ -2800,6 +2816,8 @@ def simple_declaration(self, by_reference=False, *, in_parser=False):
name = self.parser_name
else:
name = self.name
if self.unused:
name = f"Py_UNUSED({name})"
prototype.append(name)
return "".join(prototype)

Expand Down

0 comments on commit b2c1b4d

Please sign in to comment.