1

I use the following code to create subclasses of class G and pass them the type of model they should produce.

from typing import TypeVar, Type


class A:
    @classmethod
    def model_validate(cls):
        print('Done')


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


class G[T]:
    def __init__(self, model: Type[T]):
        self.model = model

    def func(self) -> None:
        print(self.model.model_validate())


G[A](A).func()

This works fine, but mypy gives this error:

error: "type[T]" has no attribute "model_validate"  [attr-defined]

What am i doing wrong?

New contributor
KOLYAN CAT4UP is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

1 Answer 1

1

You are mixing up two type variables. T = TypeVar... defines a typevar with bound, then G[T] completely disregards that, creates a new typevar (with no bound) and uses it.

Either use old-style generics (playground):

from typing import Generic, TypeVar

class A:
    @classmethod
    def model_validate(cls) -> None:
        print('Done')

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

class G(Generic[T]):
    def __init__(self, model: type[T]) -> None:
        self.model = model

    def func(self) -> None:
        print(self.model.model_validate())


G[A](A).func()

or new-style PEP695 generics (playground):

class A:
    @classmethod
    def model_validate(cls) -> None:
        print('Done')

class G[T: A]:
    def __init__(self, model: type[T]) -> None:
        self.model = model

    def func(self) -> None:
        print(self.model.model_validate())


G[A](A).func()

Both are accepted by mypy. Also note that you don't need typing.Type if you're using a non-EOL python version (built-in type should be used instead since 3.9 as shown above).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.