I wonder if, and then how, in pydantic
, one could have a field whose type is determined by the value of another field, e.g., as follows:
from pydantic import BaseModel
class Example(BaseModel):
type: str
value: MyType[type] # not possible and wrong syntax, but ...
Let's say I want to have instances with int or complex:
ex1 = Example(type="int", value = 5) # or maybe MyType("int",5)
ex2 = Example(type="complex", value=1 2j) # or maybe MyType("complex", 1 2j)
Then I want ex1.value
to be validated as an integer, and ex2.value
as a complex. Ultimately I want multidimensional lists (T
, List[T]
, List[List[T]]
, etc.) carrying (where T
is) int
, float
, complex
, or str
.
Is there a nice way of doing something in that direction? (preferably in Python 3.8)
CodePudding user response:
Would something like this work for you?
from pydantic.generics import GenericModel
from typing import Generic, TypeVar, TYPE_CHECKING
T = TypeVar('T')
class Example(GenericModel, Generic[T]):
value: T
ex1 = Example[int](value=5)
ex2 = Example[complex](value=1 2j)
if TYPE_CHECKING:
reveal_type(ex1.value)
reveal_type(ex2.value)
Output:
$ mypy program.py
program.py:13: note: Revealed type is "builtins.int"
program.py:14: note: Revealed type is "builtins.complex"
Success: no issues found in 1 source file
If you want to have a type attribute you can add it like this:
from pydantic.generics import GenericModel
from typing import Generic, Type, TypeVar, TYPE_CHECKING
T = TypeVar('T')
class Example(GenericModel, Generic[T]):
type: Type[T]
value: T
ex1 = Example[int](type=int, value=5)