Search code examples
pythonpython-typingmypy

Python: type-hinting a classmethod that returns an instance of the class, for a class that is inherited


Consider the following:

from __future__ import annotations

class A:

    def __init__(self):
        print("A")
        self.hello = "hello"

    # how do I type this so that the return type is A for A.bobo()
    # and B for B.bobo()?
    @classmethod
    def bobo(cls) -> UnknownType:
        return cls()


class B(A):

    def __init__(self):
        print("B")
        super().__init__()
        self.world = "world"


instance_of_B = B.bobo()  # prints "B", then "A", and returns an instance of B

I want to type-hint the bobo class method, so that mypy can know that in the case of B's bobo method, it's not just an instance of A that's returned, but actually an instance of B. I'm really unclear on how to do that, or if it's even possible. I thought that something like Type[cls] might do the trick, but I'm not sure if that even makes syntactic sense to mypy.


Solution

  • You will have to use a TypeVar, thankfully, in Python 3.11 the typing.Self type is coming out. This PEP describes it in detail. It also specifies how to use the TypeVar until then.