4

In Python 3.5, I'd like to use type hinting on a class method that returns a new instance of a class.

For example, I've got the following two classes:

class A:
    @classmethod
    def new_thing(cls):
        return cls()

class B(A):
    pass

I'd like to add a type hint to new_thing to specify that it returns an instance of the class it's called from.

The closest solution I've found is to use TypeVar, e.g.:

from typing import Type, TypeVar

T = TypeVar('T')

class A:
    @classmethod
    def new_thing(cls: Type[T]) -> T:
        return cls()

However, this doesn't indicate any constraints on the type of cls, whereas cls should always be a instance of A or one of its subclasses (i.e. there's nothing to hint that cls should be callable here).

Is there some way to achieve this? TypeVar has a bound argument, so a first thought was:

T = TypeVar('T', bound=A)

but this doesn't work, as A isn't defined when the TypeVar is declared (and I can't declare A without the T first being defined).

Dave Challis
  • 3,525
  • 2
  • 37
  • 65
  • 4
    I don't think the dupe exactly answers your question, but in any case, you were pretty close -- the only thing you need to change is to do is to make your typevar to use a [forward reference](https://www.python.org/dev/peps/pep-0484/#forward-references) -- that is, do `T = TypeVar('T', bound='A')`. – Michael0x2a Jul 21 '17 at 00:11
  • In python < 3.7 I'd use: `from typing import Type class A: @classmethod def new_thing(cls: Type['A']) -> 'A': return cls()` – NDonelli Aug 04 '21 at 16:55

0 Answers0