pythongenericspython-typingpydantic

Nested Pydantic Models and Generics


I am trying to reduce some code duplication by using generic types in python. With this minimal example

from typing import Generic, TypeVar
from pydantic import BaseModel

T = TypeVar("T")

class Foo(BaseModel, Generic[T]):
    a: T

Bar = list[Foo[T]]

class Baz(BaseModel, Generic[T]):
    b: Bar[T]

I get the following type error:

TypeError: There are no type variables left in list[__main__.Foo]

It works all fine if I replace the alias Bar in the Baz class by list[Foo[T]], so is this a general issue with aliases? Thanks.


Solution

  • You do not need to define Bar[T] again:

    class Baz(BaseModel, Generic[T]):
        b: Bar
    

    So b is defined as Bar, which you already give a list with generic [T].

    from typing import Generic, TypeVar
    from pydantic import BaseModel
    
    T = TypeVar("T")
    
    class Foo(BaseModel, Generic[T]):
        a: T
    
    Bar = list[Foo[T]]
    
    class Baz(BaseModel, Generic[T]):
        b: Bar
    

    I am not sure what you try to accomplish, but I do not think that it does what you hope/think it will do:

    Bar=[Foo(a=1), Foo(a=1.0)]
    

    is valid (i.e. no validation error), but it looks like that you want that in a list all variables of Foo are the same (i.e. that they are cast to int or float). That is not happening now, so it makes less sense to use pydantic, since the most valuable addition of pydantic over a normal calss are the validations.