Jean-Francois T.
Jean-Francois T.

Reputation: 12958

Mypy annotation on a class decorator

I'm using class decorators in Python and cannot figure out which type annotation to give to my class to make mypy happy.

My code is the following:

from typing import Type
from pprint import pformat


def betterrepr(cls:Type[object]):
    """Improve representation of a class"""

    class improved_class(cls):  # line 12
        def __repr__(self) -> str:
            return f"Instance of {cls.__name__}, vars = {pformat(vars(self))}"

    return improved_class

I'm currently having the 2 following errors:

myprog.py:12: error: Invalid type "cls"

myprog.py:12: error: Invalid base class

What shall I use for the type of cls (and by the way, is it Pythonic to use this keyword for a class used as argument?)?

Thanks

Upvotes: 8

Views: 7054

Answers (1)

MisterMiyagi
MisterMiyagi

Reputation: 52169

Using function arguments as base classes is currently not supported by mypy. Your only option is to silence the error, either with a type: ignore comment or a dummy alias like base: Any = cls.

Even without annotating cls, mypy will correctly infer the type of a class decorated with betterrepr. To document that your decorator returns a class similar to the decorated class, use a TypeVar.

from typing import Type, TypeVar
from pprint import pformat

T = TypeVar('T')


def betterrepr(cls: Type[T]) -> Type[T]:
    """Improve representation of a class"""
    class IClass(cls):  # type: ignore
        def __repr__(self) -> str:
            return f"Instance of {cls.__name__}, vars = {pformat(vars(self))}"
    return IClass

Upvotes: 7

Related Questions