I have a model defined like this;
class SomeModel(BaseModel):
name: str
class SomeOtherModel(BaseModel):
name: int
class MyModel(BaseModel):
items: List[Union[SomeModel, SomeOtherModel]]
@validator("items", always=True)
def validate(cls, value):
by_type = list(filter(lambda v: isinstance(v, SomeModel), value))
if len(by_type) < 1:
raise ValueError("we need at least one SomeModel")
The submodels are unimportant, essentially I need a list of different sub-models, and the list must contain at least one of the first type. All well and good.
Elsewhere in my code I am referring to this model (context: for the purposes of saving user settings, should be irrelevant for this question).
class ComposerModels(BaseModel):
user: List[MyModel] = []
system: List[MyModel] = []
class ComposerSettings(BaseModel):
models: ComposerModels
class UserSettings(BaseModel):
composer: ComposerSettings
My program needs to be able to save new models into the UserSettings model, something like this;
my_model = MyModel(items=[SomeModel(name="a"), SomeOtherModel(name=1)])
user_settings = UserSettings(
composer=ComposerSettings(
models=ComposerModels(
user=[my_model]
)
)
)
However, this throws an error;
Traceback (most recent call last):
File ".../pydantic/shenanigans.py", line 38, in <module>
user=[my_model]
File "pydantic/main.py", line 342, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for ComposerModels
user -> 0
we need at least one SomeModel (type=value_error)
This is where it gets weird.
For some reason, when trying to instantiate UserSettings
, it goes through validation of the items
field inside MyModel
, but instead of having been passed a list of sub-models, as expected, somehow it’s getting a list of MyModel instances instead. This obviously fails validation, and raises the error above. However, if I comment out the validation code, it works. No error, and the user settings model contains the MyModel
we’d expect.
I can’t just disable that validation, I need it elsewhere in my program… Any ideas on what’s going on here? I’m stumped…
I’m running python 3.7 with pydantic 1.10 on centos 7. I can’t easily upgrade any versions, because my company doesn’t believe in devops, so if this is a known bug with pydantic at that version I’ll have to think of something else.