Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I correctly add type-hints to Mixin classes?

Tags:

Consider the following example. The example is contrived but illustrates the point in a runnable example:

class MultiplicatorMixin:      def multiply(self, m: int) -> int:         return self.value * m   class AdditionMixin:      def add(self, b: int) -> int:         return self.value + b   class MyClass(MultiplicatorMixin, AdditionMixin):      def __init__(self, value: int) -> None:         self.value = value   instance = MyClass(10) print(instance.add(2)) print(instance.multiply(2)) 

When executed this will give the following output:

12 20 

The code works.

But running mypy on it, yields the following errors:

example.py:4: error: "MultiplicatorMixin" has no attribute "value" example.py:10: error: "AdditionMixin" has no attribute "value" 

I understand why mypy gives this result. But the mixin classes are never used by themselves. They are always used as additional superclasses.

For context, this is a pattern which has been used in an existing application and I am in the process of adding type-hints. And in this case, the errors are false-positives. I am thinking about rewriting the part using the mixins as I don't particularly like it and the same could probably be done with reorganising the class hierarchy.

But I still would like to know how something like this could be properly hinted.

like image 556
exhuma Avatar asked Aug 20 '18 12:08

exhuma


People also ask

What is a mixin type?

In object-oriented programming languages, a mixin (or mix-in) is a class that contains methods for use by other classes without having to be the parent class of those other classes.

Should I use type hints?

Type hints help you build and maintain a cleaner architecture. The act of writing type hints forces you to think about the types in your program. While the dynamic nature of Python is one of its great assets, being conscious about relying on duck typing, overloaded methods, or multiple return types is a good thing.

What are mixin methods?

A mixin is a class such that some method of the class uses a method which is not defined in the class. Therefore the class is not meant to be instantiated, but rather serve as a base class. Otherwise the instance would have methods that cannot be called without raising an exception.

What are type hints for?

Introduction to Type Hints As the code base gets larger, type hints can help to debug and prevent some dumb mistakes. If you're using an IDE like PyCharm, you'll get a warning message whenever you've used the wrong data type, provided you're using type hints.


1 Answers

For reference, mypy recommends to implement mixins through a Protocol (documentation here).

It works with mypy >= 750.

from typing import Protocol   class HasValueProtocol(Protocol):     @property     def value(self) -> int: ...   class MultiplicationMixin:      def multiply(self: HasValueProtocol, m: int) -> int:         return self.value * m   class AdditionMixin:      def add(self: HasValueProtocol, b: int) -> int:         return self.value + b   class MyClass(MultiplicationMixin, AdditionMixin):      def __init__(self, value: int) -> None:         self.value = value 

The Protocol base class is provided in the typing_extensions package for Python 2.7 and 3.4-3.7.

like image 164
Campi Avatar answered Oct 06 '22 04:10

Campi