19

For my code in Python, I would like to call many functions with a specific argument. However, for some functions, that argument does not do anything. Still, I would like to add the argument for compatibility reasons. For example, consider the following minimal working example:

def my_function(unused=False):
    """ Function with unused argument. """
    return True

Obviously, the argument unused is not used, so Pylint throws a warning:

W0613: Unused argument 'redundant' (unused-argument)

My point is that I do not want to remove the argument unused, because the function my_function will be called in a similar way as many other functions for which unused is used.

My question: How can I avoid the warning from Pylint without removing the optional argument?

Option 1: I can think of two options, but these options do not satisfy me. One option is to add some useless code, such that unused is used, e.g.,

def my_function(unused=False):
    """ Function with unused argument. """
    if unused:
        dummy = 10
        del dummy
    return True

This feels as a waste of resources and it only clutters the code.

Option 2: The second option is to suppress the warning, e.g., like this:

def my_function(unused=False):
    """ Function with unused argument. """
    # pylint: disable=unused-argument
    return True

I also do not really like this option, because usually Pylint warnings are a sign of bad style, so I am more looking to a different way of coding that avoids this warning.

What other options do I have?

EdG
  • 328
  • 1
  • 2
  • 8
  • I believe it would help if you could mention how you intend to call these functions. Looks like you want to have a consistent signature for a whole group of functions so that you can call them all in a similar fashion. How exactly do you want to call the functions? – sinoroc Dec 02 '19 at 11:12
  • Each function is producing a figure of a traffic situation. I use an argument to tell whether it is right-hand driving or left-hand driving (so the `unused` argument in the above example is used to tell if we use right-hand driving or left-hand driving). For some figures, however, the result is the same for left-hand driving as for right-hand driving, so the argument is not used at all. I group all functions (that produce these figures) in a list and execute them one by one. So something on the line of `[func(unused=True) for func in [my_function, my_function2]]`. Does this help you? – EdG Dec 02 '19 at 11:49
  • Yes, it helps, it means the name of the argument has to be the same in all functions, and so the trick with the leading underscore (`_unused`) can not be used. You could probably work something out with `**kwargs` though. – sinoroc Dec 02 '19 at 12:01
  • 1
    Yes, changing the name is not an option. Actually, I was already thinking of `**kwargs`, especially when I will use more input arguments (which I will eventually do, I think)., so this is a good suggestion from you. – EdG Dec 02 '19 at 13:20
  • Actually after trying a bit, I don't believe using `**kwargs` is much better. _pylint_ will end up triggering the `unused-argument` message for `kwargs` instead of `unused`, with the added drawback of being less readable. But maybe it suits your use cases better. – sinoroc Dec 02 '19 at 14:05

2 Answers2

21

I do not believe disabling some pylint warnings is bad style, as long as it is done carefully with clear intent and as specific as possible. For this purpose it is important to activate the useless-suppression check. When it is active pylint will warn you if some messages are locally disabled for no good reason. Add this to your .pylintrc:

[MESSAGES CONTROL]
enable=useless-suppression

For example I would recommend disabling the exact occurrence of the issue like in the following example:

def my_function(
        used,
        unused=False,  # pylint: disable=unused-argument
):
    """ Function with unused argument. """
    return used

Adding a leading underscore should also keep pylint from triggering:

def my_function(used, _unused=False):
    """ Function with unused argument. """
    return used

Another commonly used pattern is the following:

def my_function(used, unused_a, unused_b=False):
    """ Function with unused argument. """
    _ = (unused_a, unused_b,)
    return used
sinoroc
  • 18,409
  • 2
  • 39
  • 70
  • 1
    Thank you for your answer. I see your first option as an improvement of my second option, because in your case, we only disable the warning for a specific argument rather than for all arguments of `my_function`. So thank you for that (+1). I will wait a bit before accepting your answer, such that other are not demotivated to give other answers. – EdG Dec 02 '19 at 11:03
  • The underscore prefix was the perfect solution for me, thanks. – dhochee May 18 '21 at 21:17
  • 2
    @dhochee Obviously, prefixing a keyword argument with an underscore changes the name of that keyword argument, so is unlikely to be a usable solution in cases where the argument actually *needed* to be a keyword argument. – Ian Goldby Feb 17 '22 at 10:51
  • 1
    I use `Pylance` and `SonarLint` and the last solution (`_ = unused_argument`) is the only one that worked for me. Thanks a lot – Jean-Francois T. Apr 30 '22 at 14:21
2

It would be possible to work out a solution by playing around with **kwargs. For example:

def _function_a(one, two=2):
    return one + two

def _function_b(one, **kwargs):
    return one + kwargs['two']

def _function_c(one, **_kwargs):
    return one

def _main():
    for _function in [_function_a, _function_b, _function_c]:
        print(_function.__name__, _function(1, two=4))
sinoroc
  • 18,409
  • 2
  • 39
  • 70