Skip to content

Proposal for mapping Python types to CombinedValidator #1337

Open
@adriangb

Description

@adriangb

Currently because of configs it is not possible to map a type to a SchemaValidator or CoreSchema. Consider:

class Inner(BaseModel):
    x: dict[str, list[float]]

    model_config = ConfigDict(allow_inf_nan=False)

class Outer(BaseModel):
    inner: Inner
    x: dict[str, list[float]]

    model_config = ConfigDict(allow_inf_nan=True)

Edit by @Viicos: allow_inf_nan actually doesn't seem to alter the core schema of x. One example that does however is use_enum_values.

Because of this we can’t just have a type_cache: dict[type, CoreSchema] when we build a schema from types in Pydantic: although dict[str, list[float]] shows up in two places the actual schema differs because of the model config.

To get around this I propose that we establish a rule: “every validator must be derivable from the type and only the type”. That means that all of the things coming from configs have to live elsewhere. For this I propose we (1) move all config things to ValidationState and (2) introduce a validator that mutates ValidationState to set the current config.

For example, we’d have {‘type’: ‘config’, ‘config’: {‘allow_inf_nan’: True}, ‘schema’: {…}}. At runtime this would mutate the validation context. And FloatValidator would pull that configuration from the context instead of storing it on the struct. Now both CoreSchema::Float and FloatValidator are immutable respect to the type and thus we can map from a type to a CoreSchema or SchemaValidator.

I expect this will slightly simplify some code (it essentially merges runtime parameters and compile time parameters into one code path where compile time just means a compile time defined mutation of runtime parameters) and have a minimal performance impact (we can still convert all configs to rust structs ahead of time, it’s just a struct being passed in through context vs hardcoded on the validator).

I think we might as well also establish or consider current behavior wrt rules for config merging and interaction with runtime parameters.

@davidhewitt @sydney-runkle wdyt?

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions