2

I have such class:

from typing import Generic, TypeVar
from pydantic import BaseModel

T = TypeVar("T", bound=BaseModel)

class A(Generic[T]):
    def some_method(self) -> T:
        ... # some data processing
        return T.from_orm(some_data_model)

# in tests package:
class Model(BaseModel): ...
A[Model].some_method()
assert Model.from_orm.called_once

But it doesn't work because T is not a real type(BaseModel) but only TypeVar that bounds to BaseModel.

So the question is: how can I get the real(substituted) type T?

Important notes:

it doesn't matter for me what the type the method is(classmethod, method of object instance or staticmethod)

my python version is 3.8

This answer doesn't helped me:

I tried this:

from typing import ..., get_args
#   ...
    def some_method(self) -> T:
        ...
        return get_args(type(self))[0].from_orm(some_data_model)

This:

from typing import ..., get_args
#   ...
    @classmethod
    def some_method(cls) -> T:
        ...
        return get_args(cls)[0].from_orm(some_data_model)

And this:

from typing import ..., get_args
#   ...
    @classmethod
    def some_method(cls) -> T:
        ...
        return get_args(A)[0].from_orm(some_data_model)

And I call it in a such way(if it is class/static method):

A[Model].some_method()

And if it is instance method:

A[Model]().some_method()

And all of it(without calling from_orm and getting index 0) just returns empty tuple and the whole method ends with IndexError(which is totally right).

sakost
  • 250
  • 4
  • 15
  • 1
    Related https://stackoverflow.com/questions/66927793/how-to-use-isinstance-on-a-generic-type-in-python/ – alex_noname Nov 16 '21 at 19:38
  • @alex_noname oh, I wasn't able to find the answer with `__orig_class__`. thank you! I'm going to write the answer. – sakost Nov 16 '21 at 19:42

1 Answers1

1

In the comments @alex_noname posted a link to another such question.

In my case the answer was to use the __orig_class__ attribute of the self object:

from typing import Generic, TypeVar, get_args
from pydantic import BaseModel

T = TypeVar("T", bound=BaseModel)

class A(Generic[T]):
    def some_method(self) -> T:
        ... # some data processing
        return get_args(self.__orig_class__)[0].from_orm(some_data_model)

For more information please refer to this answer

sakost
  • 250
  • 4
  • 15