Skip to content

Support Pydantic validators in Annotated fields #4256

Description

@stijndcl

Pydantic has support for validators (docs) which allow transforming an input value before storing it in the model. It seems like the @field_validator decorator pattern should be supported (see prior issues like #589), but the Annotated[T, *V] pattern is not.

As a very simple example:

from typing import Annotated, Any
from pydantic import BaseModel, BeforeValidator

def ensure_str(v: Any) -> str:
    return str(v)

class MyModel(BaseModel):
    field: Annotated[str, BeforeValidator(ensure_str)]

MyModel(field=5) # You can pass in other things here, but Pyrefly doesn't allow it

The example above can take in any value, convert it to a string, and store it as such in the model field. Pyrefly, however, only looks at the str argument of the Annotated type, and completely ignores the validators that come after. It only allows assigning a str to this field, even though I should be able to pass in whatever I want.

If validators are supplied, Pyrefly should let you assign whichever value the first validator allows. In my example above this would be Any, but that doesn't have to be the case. Ideally, this would respect model_config.validate_assignment to correctly typecheck on assignment after __init__ as well.

Similarly, it would make sense to have a check for the output value of the validator to be compatible with the supposed type of the field, meaning that -> str is assignable to Annotated[str, ...].

It could go further and check that chained validators are compatible with eachother, but that might be out of scope for this issue as it seems quite complicated.

Why not just use the decorator pattern?

This allows extracting the validators out to a custom type that you can attach to fields, rather than having to write a validator function for every single field every single time. For large models that have a lot of fields that need pre-processing, this saves a lot of effort.

Metadata

Metadata

Labels

help wantedLarger than "good first issue", but still well-defined and ready for someone to pick uppydanticIssues related to support for Pydantictypechecking

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions