pythontype-hintingtype-annotation

What should I type hint 'self' of functions in a Mixin Class with multiple functions depending on each other


Assume I have below Mixin class, and it assumes the class inherits it has property value. However, PyLance is not happy with this code given self.value is not defined in foo_mixin

class foo_mixin:

    def f1(self, a:int) -> int:
        return self.value + a

    def f2(self, a:int) -> int:
        return self.f1(a) - a

Then I tried to type hint 'self' with some protocol, like below:

from typing import Protocol
class value_protocol(Protocol):
    @property
    def value(self) -> int: ...

And foo can is now defined as below:

class foo_mixin:

    def f1(self:value_protocol, a:int) -> int:
        return self.value + a

    def f2(self:value_protocol, a:int) -> int:
        return self.value * self.f1(a) - a

But value_protocol does not contain f1, so Pylance now is angry with me about f1 by saying

Cannot access member "f1" for type "value_protocol".
Member "f1" is unknown Pylance

My question is how should I type hint self in this case.


Solution

  • Make foo_mixin an ABC, with value an abstractproperty:

    from abc import ABC, abstractproperty
    
    class foo_mixin(ABC):
    
        @abstractproperty
        def value(self) -> int: ...
    
        def f1(self, a:int) -> int:
            return self.value + a
    
        def f2(self, a:int) -> int:
            return self.value * self.f1(a) - a
    

    Now any concrete class which inherits foo_mixin is required to implement value, which makes it safe for any instance of foo_mixin to access self.value.