Search code examples
pythonpython-typingpyright

Python typing annotation for an object built with a class method


Here's a code snippet.

from typing import Generic, TypeVar, Union

T = TypeVar('T')

class Bar(object):
    def __init__(self, blah: Union[int, str]) -> None:
        self.blah = blah

class Foo(Generic[T]):

    def __init__(self, bar: T) -> None:
        self.bar = bar

    @classmethod
    def extract(cls, klass: T) -> 'Foo':
        return cls(bar=klass(123))

foo = Foo.extract(Bar)
foo.bar # typing says "Any"

foo1 = Foo(Bar(123))
foo1.bar # typing says "Bar" as expected

When I try to create an object with a class method the typing annotation is not working as expected.

Screenshot of annotation not working

However if I build the object directly then it works just fine. Screenshot of annotation working

I'm using VSCode with latest version of pylance and python extension as writing this question.

Please let me know if this is not possible or if I'm doing something wrong here.

The typing of the object created by the classmethod to have the annotation.


Solution

  • So, you are specifying:

    @classmethod
    def extract(cls, klass: T) -> 'Foo':
    

    but Foo is implicitly Foo[Any], if you don't provide a type parameter. You want:

    @classmethod
    def extract(cls, klass: T) -> 'Foo[T]':