1

I am getting a type warning when implementing an abstractmethod in a more explicit way, why is that wrong?

I have the following interface

from typing import Any
from abc import abstractmethod, ABCMeta

class SaveDataInterface(metaclass=ABCMeta):
    @abstractmethod
    def save_data(self, data: Any, *args, **kwargs):
        ...

When implementing the following FileSaver class, mypy throws an error
error: Signature of "save_data" incompatible with supertype "SaveDataInterface"

class FileSaver(SaveDataInterface):
    def save_data(self, data: str, file_path: str, *args, **kwargs):
        with open(file_path, 'w') as file:
            file.write(data)

It doesn't seem to me that FileSaver.save_data somehow breaks the abstractmethod save_data functionality, Is there another way to implement a more explicit function signature?

moshevi
  • 4,999
  • 5
  • 33
  • 50
  • 1
    If a type S is a subtype of type T, then you want to be able to replace T everywhere with S without altering behavior (i.e. Liskov Substitution Principle). In your case, because parent-class SaveDataInterface takes *more general argument types* you can't use the child class, which takes *less generaly* argument types. So, overriden methods must be contra (or co) variant in there *argument types*, but not in their *return types*. See: https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Inheritance_in_object-oriented_languages – juanpa.arrivillaga Sep 24 '20 at 14:50
  • 1
    So, in Python, you are free to do this, but it isn't type-safe, and mypy correctly complains – juanpa.arrivillaga Sep 24 '20 at 14:51

0 Answers0