2

Could I get some help understanding what the pylint message Signature differs from overidden 'save' method, pylint(signature-differs) is referring to?:

def save(self, *args, **kwargs):
    """
    Override the original save method and update the number of
    seats available
    """
    reservations = (
        Booking.objects.aggregate(
            num_passengers=Count("passengers")
        )
        ["num_passengers"] or 0
    )
    self.seats_available = self.destination.max_passengers - reservations
    super().save(*args, **kwargs)

The Django docs says "If you use *args, **kwargs in your method definitions, you are guaranteed that your code will automatically support those (updated method) arguments when they are added."

I don't fully comprehend how signatures work but my understanding is that it's to do with making sure parameters match. In this case I don't think I have changed anything from the default save method...so what is causing the issue?

fdeboo
  • 325
  • 1
  • 11

1 Answers1

1

I've just come across this issue and have been trying to figure this out myself. I don't understand the precise specifics, but I believe I found the general reasoning.

Basically the def save(self, *args, **kwargs) is less restrictive than the save method in the Django Docs:

def save(self, force_insert=False, force_update=False, using=None,
          update_fields=None)

You'll notice that if you copy and paste the arguments from the save method from the docs instead of *args, **kwargs the error disappears.

That's because using *args, **kwargs as arguments theoretically allows you to pass extra arguments into the method, making it violate the LSP Principle (See conversation here for a clear example). The arguments in the substitution must be equal or more restrictive than the parent method. They should not allow you to pass in additional arguments.

However, in practice, Django won't ever do this unless you code it to do that yourself, so I think it's relatively unimportant as a warning in this case. I suppose the Django developers recommend the shorthand *args, **kwargs as it is easier to use as a substitute in lots of methods, without having to remember the specific arguments for each separate class or method. I guess it falls under one of the Python style guide recommendations when it is better to be inconsistent with recommendations.

Hope that helps somewhat!

ChrisF
  • 134,786
  • 31
  • 255
  • 325
qqqqq
  • 34
  • 8