Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 321
Tristan Duquesne Avatar asked Jan 22 '26 01:01

Tristan Duquesne


1 Answers

For an example of how to apply Brian's answer:

  • with a TypeVar:
from typing import TypeVar


AnyA = TypeVar("AnyA", bound="A")


class A:

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

    @classmethod
    def bobo(cls: type[AnyA]) -> AnyA:
        return cls()

class B(A):

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

reveal_type(B.bobo())  # B
  • with Self:
from typing import Self

class A:

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

    @classmethod
    def bobo(cls) -> Self:
        return cls()

class B(A):

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

reveal_type(B.bobo())  # B

If your version of Python doesn't have Self yet, you can use the typing-extensions package, which serves as backport for some typing features:

- from typing import Self
+ from typing_extensions import Self
like image 158
decorator-factory Avatar answered Jan 25 '26 13:01

decorator-factory



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!