Class Decorator Compatible for Mypy

491 Views Asked by At

Say I have the following simple example without any typehints:

def wrapper(cls):
    class Subclass(cls):
        def subclass_method(self):
            pass
    return Subclass


@wrapper
class Parent:
    def parent_method(self):
        pass


p = Parent()
p.parent_method()
p.subclass_method()

How can I restructure this code using typehints, such that when I run mypy against an instance of Parent, it will recognize both subclass_method and parent_method?

Possible solutions:

  • Using a mixin Parent(Mixin): Works, but avoids the decorator. Is it possible to achieve without?
  • Patching the method onto the existing class: Still has the same issue of resolving subclass_method in mypy
  • Custom Mypy plugin: Wouldn't be sure where to start with this one, or if it would be possible without one.
1

There are 1 best solutions below

9
On

This would be much simpler without the wrapper at all.

class SomeMixin:
    def subclass_method(self):
        pass


class Parent(SomeMixin):
    def parent_method(self):
        pass


p = Parent()
p.parent_method()
p.subclass_method()

Here, you define SomeMixin once, not once per call to a wrapper, and the class SomeMixin is known statically. All the various classes with the name Subclass are created dynamically, and mypy can't know statically which class the name Parent is actually bound to.