Search code examples
pythongenericspython-typing

How to verify if a instance of a generic class is from the good type variable in python3?


Let's assume that I have a generic class like that :

import typing

type_variable = typing.TypeVar("type_variable")

class OneClass(typing.Generic[type_variable]):
    def __init__(self, value: type_variable):
        self.value = value

Now I create two simple objects :

a = OneClass("a str-typped object")
b = OneClass(b'a byte-typped object')

When I check if a and b have same type using type, it says True :

>>> type(a) == type(b)
True

When I check if a is of type OneClass[str], it says False:

>>> type(a) == OneClass[str]
False

I know that there I can use something like type(a.value) == type(b.value), but in some other cases I can have this kind of objects :

tuple_object_1 = OneClass(("a", "first", "tupple", "with", "strings"))
tuple_object_2 = OneClass((b'a', b'second', b'tupple', b'with', b'bytes'))

In that case I have as types :

  • tuple_object_1 : OneClass[tuple[str]]
  • tuple_object_2 : OneClass[tuple[bytes]]

and so evaluating the types of tuple_object_1 and tuple_object_2 only returns tuple and not something like tuple[str] and tuple[bytes], so the type evaluation of the content is also not valid.

How can I get the type of those kind of objects, considering also their generic types? Something like a deep type.

Thanks for help!


Solution

  • You are making a fundamental error. You are confusing types (int, float, OneClass) with type annotations (all the previous types, as well as OneClass[int], tuple[int, ...], etc.)

    As far as Python is concerned, tuple_object_1 and tuple_object_2 are just tuples, nothing more. It doesn't care in the least what the types of the elements are within the tuple until you actually access them.

    Type annotations are used by IDEs and checkers to verify the correctness of your code. If you declare something to be List[int], it will be your IDE or your lint checker that warns you if you try to add a string to it. But Python couldn't care less.