Pydantic prevent conversion of incorrect type

Viewed 2390

Pydantic appears to perform automatic type conversion when the type of a property is not what is expected. I believe this is why (conveniently) it is possible to assign the value of an int enum property of a class via its raw int value.

However I have a scenario where I want to avoid this behaviour and instead receive a validation error if a property is not of the expected type. See the following example:

from pydantic import BaseModel
from typing import List

class Common(BaseModel):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        print(f"created {self.__class__.__name__} with {kwargs}")

class Child(Common):
    child_prop: int = None

class Parent(Common):
    child: Child

class Imposter(Common):
    imposter_prop: int

parent = Parent(
    child=Imposter(imposter_prop=0)
)
print(f"is child: {isinstance(parent.child, Child)}")

Output from executing this module:

created Imposter with {'imposter_prop': 0}
created Child with {'imposter_prop': 0}
created Parent with {'child': Imposter(imposter_prop=0)}
is child: True

As you can see Pydantic happily allows me to create a Parent with an Imposter object for the property that should be Child. It supports this by creating a Child using the properties of the Imposter. I don't want this to happen.

I've looked through the Pydantic docs but none of the configuration options are jumping out at me as candidates to change this behaviour. Is there anything I can do to prevent this attempted type conversion?

1 Answers

If you were using something with builtin types and wanted to prevent coercion, you could utilize pydantic strict types. Given you are custom types, I believe you may need to explicitly define your own validate(cls, v) @classmethod etc in your custom types. They provide an example for custom data type validation, including usage of isinstance that you will want to utilize.

Related