-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Different behavior of model_validate/model_validate_json with type fields #6573
Comments
This is an interesting case. The interesting bit of the {
'type': 'custom-error',
'schema': {'type': 'is-instance', 'cls': type},
'custom_error_type': 'is_type',
'custom_error_message': 'Input should be a type'
} To me, what it looks like is happening is that At the very least we should improve the error message, potentially we can even just support this case outright. |
Testing locally, if I change the check in https://github.com/pydantic/pydantic-core/blob/main/src/validators/is_instance.rs#L67 This is because the It's not clear to me whether changing that is a bad idea? Should instead adjust the schema for |
I'm not sure either. I think changing the schema for the arbitrary types fallback to ignore json makes more sense. |
This is what I think (or would like to) be happening behind the scenes: from typing import Any
from pydantic_core import SchemaValidator, core_schema
class Dummy:
pass
def set_type(v: dict[str, Any]) -> dict[str, Any]:
return {'object_type': Dummy}
cs = core_schema.no_info_before_validator_function(
set_type,
core_schema.typed_dict_schema(
{
'object_type': core_schema.typed_dict_field(
core_schema.json_or_python_schema(
json_schema=core_schema.any_schema(),
python_schema=core_schema.is_instance_schema(type),
)
)
}
)
)
v = SchemaValidator(cs)
assert v.validate_json('{}') == {'object_type': Dummy} |
MRE: from typing import Any
from pydantic import BaseModel, ConfigDict, model_validator
class Dummy:
pass
class Loader(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
object_type: type
@model_validator(mode='before')
def validate_all(cls, _values: dict[str, Any]) -> dict[str, Any]:
return {"object_type": Dummy}
assert Loader.model_validate_json('{}') == {'object_type': Dummy} |
Initial Checks
main
branch, or equivalentDescription
We are using generic loader classes to serialize/deserialize callable methods and objects. While migrating to v2, noticed discrepancies between parse_raw and model_validate_json that prevented proper validation of type fields. Interestingly, overriding the inputs in @model_validation(mode='before') completely and supplying same dictionary to model_validate and model_validate_json resulted in only the latter raising an exception. So something in the parsing logic is different for (mode='before'), but the error message is seems to indicate it should work. Both methods work with (mode='after').
It is a bit hard to explain coherently, so please refer to example below.
Output:
Example Code
Python, Pydantic & OS Version
Selected Assignee: @davidhewitt
The text was updated successfully, but these errors were encountered: