9

Using PEP 484, is there a way to annotate that a classmethod returns an instance of that class?

e.g.

@dataclass
class Bar:

    foo: str

    @classmethod
    def new_from_foo(cls, foo) -> Bar
        ...

or

    @classmethod
    def new_from_foo(cls, foo) -> cls
Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
Gary van der Merwe
  • 9,134
  • 3
  • 49
  • 80

1 Answers1

12

The trick is to use a TypeVar to connect the cls parameter to the return annotation:

from typing import TypeVar, Type

T = TypeVar('T')

class Bar:
    @classmethod
    def new_from_foo(cls: Type[T], foo) -> T:
        ...
Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
  • This works, but somehow dose not work with dataclasses. I will investigate to try understand why. – Gary van der Merwe Aug 02 '18 at 08:08
  • @GaryvanderMerwe Huh, you're right. I didn't realize. I'll investigate that. – Aran-Fey Aug 02 '18 at 08:11
  • 3
    Looks like a bug in mypy to me, honestly. As far as I can tell, it only happens in classmethods - and only in dataclasses. Edit: Found the relevant [github issue](https://github.com/python/mypy/issues/5263). – Aran-Fey Aug 02 '18 at 08:24