0

I want to validate a field in a pydantic model that is a subclass of another model. The class assigned to this field can change, but will always be a subclass of this specific model.

I am getting an error that should not be occurring given the inheritance and sub-class definition of the models. I do not think this should be happening. I have reported the bug on the github repo.

I have created a reprex so you can see the error firsthand:

from fastapi.datastructures import QueryParams
from pydantic import ConfigDict, Field, BaseModel
from humbldata.core.standard_models.abstract.humblobject import HumblObject
from humbldata.core.standard_models.toolbox import ToolboxQueryParams
from humbldata.core.standard_models.toolbox.technical.mandelbrot_channel import MandelbrotChannelQueryParams


class Model(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)
    command_params: QueryParams = Field()

    # @field_validator("command_params")
    # def validate_command_params(cls, v):
    #     if issubclass(type(v), QueryParams):
    #         return v
    #     raise TypeError("Wrong type for 'some_foo', must be subclass of Foo")


Model(command_params=MandelbrotChannelQueryParams())

I get this error:

---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
Cell In[23], line 19
     10     command_params: QueryParams = Field()
     12     # @field_validator("command_params")
     13     # def validate_command_params(cls, v):
     14     #     if issubclass(type(v), QueryParams):
     15     #         return v
     16     #     raise TypeError("Wrong type for 'some_foo', must be subclass of Foo")
---> 19 Model(command_params=MandelbrotChannelQueryParams())

File c:\Users\jjfan\github\humblFINANCE-org\humbldata\menv\Lib\site-packages\pydantic\main.py:171, in BaseModel.__init__(self, **data)
    169 # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
    170 __tracebackhide__ = True
--> 171 self.__pydantic_validator__.validate_python(data, self_instance=self)

ValidationError: 1 validation error for Model
command_params
  Input should be an instance of QueryParams [type=is_instance_of, input_value=MandelbrotChannelQueryPar...False, live_price=False), input_type=MandelbrotChannelQueryParams]
    For further information visit https://errors.pydantic.dev/2.6/v/is_instance_of
2
  • you can use pip install humbldata Commented Mar 19, 2024 at 17:09
  • I think you should use Pydantic Discriminated Unions for this reason Commented Mar 19, 2024 at 17:36

1 Answer 1

0

Here is the logic for the answer:

from pydantic import BaseModel, Field
from pydantic.config import ConfigDict


class QueryParams(BaseModel):
    pass


class subQueryParams(QueryParams):
    pass


class YourModel(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)
    command_params: QueryParams = Field()


YourModel(command_params=subQueryParams())

and here is a custom validator that works if you name your subclass with a prefix to the super class:

     @field_validator("command_params")
     def validate_command_params(cls, v):
         class_name = v.__class__.__name__
         if "QueryParams" in class_name:
             return v
         msg = "Wrong type for 'command_params', must be subclass of QueryParams"
         raise TypeError(msg)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.