'Class method override with any type of property
I am trying to create a method override, and I am not sure how to make it so that the override doesn't throw the following error:
Method "main" overrides class "App" in an incompatible manner
Parameter 2 type mismatch: base parameter is type "object", override parameter is type "Tuple[str, int, int]"
"object" is incompatible with "Tuple[str, int, int]"
I Understand that the two types are different, but since object is a base class shouldn't this be allowed? I have strict turned on, so an error is thrown when I use any which is what I would like to keep turned on.
class App:
@abstractmethod
def main(self, params: object):
pass
class MyClass(App):
def main(self, params: Tuple[str, int, int]):
# Do something
What is the proper way to override a method and allow a parameter to be of any type (while using strict typing)?
Solution 1:[1]
You've got the variance backwards.
class App:
@abstractmethod
def main(self, params: object):
pass
This is a promise. It says "any class which implements App has a main which works on all objects. Not some of them. All of them.
Then you come along and write
class MyClass(App):
def main(self, params: Tuple[str, int, int]):
# Do something
So MyClass has a main which works on a specific type of parameter, not all of them. Your type checker correctly reports that this is not what you promised earlier. You could do the opposite thing: If App requires Tuple[str, int, int], then MyClass could implement a version for object, since that includes Tuple[str, int, int] and then some.
But for your case, you probably want generics.
from typing import TypeVar, Generic
_T_contra = TypeVar("_T_contra", contravariant=True)
class App(Generic[_T_contra]):
@abstractmethod
def main(self, params: _T_contra) -> None:
pass
class MyClass(App[Tuple[str, int, int]]):
def main(self, params: Tuple[str, int, int]):
# Do something
Now MyClass doesn't claim to work for all objects. It claims to work for this specific type, so it derives from a specific App.
For a discussion of why it's _T_contra (a contravariant type parameter), you can read my other answer where I go into more detail on variance annotations in Python.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Silvio Mayolo |
