TheHeadlessSourceMan
TheHeadlessSourceMan

Reputation: 747

How to use constructor of Generic type

How do I use the constructor of a python Generic typed class?

T = typing.TypeVar('T')

class MyClass(typing.Generic[T]):
    def __init__(self, initialValue: typing.Iterable):
        self.values: T = T(initialValue)

test = MyClass[tuple[int]]([1, 2, 3])

In this case I am expecting T(initialValue) to be equivalent to tuple(initialValue) but instead I get an error. "Exception has occurred: TypeError 'TypeVar' object is not callable"

I guess that's not too surprising since that's not what typing was built for, but is there a workaround to accomplish this?

Upvotes: 5

Views: 3845

Answers (1)

Silvio Mayolo
Silvio Mayolo

Reputation: 70407

You'll need to take an explicit factory method. Type annotations only exist for compile-time purposes, and at runtime that T is just a TypeVar. Consider

class MyClass(Generic[T]):
    def __init__(self, initialValue: Iterable[int], factory: Callable[[Iterable[int]], T]):
        self.values: T = factory(initialValue)

Then call it as

test = MyClass([1, 2, 3], lambda x: tuple(x))

Note: It would be nice to just pass tuple as the second argument, but mypy seems to choke when converting that typename to a Callable. Other type checkers may be able to handle it; your mileage may vary.

Upvotes: 2

Related Questions