admin管理员组

文章数量:1336624

With pydantic, is there a way for mypy to be hinted so it doesn't raise an error in this scenario, where there's a field_validator modifying the type?

class MyModel(BaseModel):
    x: int

    @field_validator("x", mode="before")
    @classmethod
    def to_int(cls, v: str) -> int:
        return len(v)


MyModel(x='test')

With pydantic, is there a way for mypy to be hinted so it doesn't raise an error in this scenario, where there's a field_validator modifying the type?

class MyModel(BaseModel):
    x: int

    @field_validator("x", mode="before")
    @classmethod
    def to_int(cls, v: str) -> int:
        return len(v)


MyModel(x='test')
Share Improve this question asked Nov 19, 2024 at 17:41 RobRob 3,4996 gold badges34 silver badges79 bronze badges 3
  • why not providing type hints as x: int | str? – Sergius Commented Nov 19, 2024 at 19:35
  • because it's not an int | str, it's an int and there's a field validator to convert it to int. This is from the docs: github/pydantic/pydantic/issues/… – Rob Commented Nov 20, 2024 at 0:44
  • imagine you have a Pydantic struct that can take an int | str, but the field value is ALWAYS an int because the field_validator will always ensure it's converted to an int. If I say int | str, now I need to validate this every time something uses the field, or I need to create a method to convert it when it's accessed. – Rob Commented Nov 20, 2024 at 0:46
Add a comment  | 

2 Answers 2

Reset to default 2

If you're always inserting a string there, it might be better to use a computed_field. Something along this, maybe?

class MyModel(BaseModel):
    input: str

    @computed_field
    def x(self) -> int:
        return len(self.input)

I think it's very counterintuitive if you see the model with the int declaration while it would raise type errors if you put an integer inside a JSON at that place.

I'm still not convinced that it's a necessary approach, but here's a really simple option how to achieve this:

from pydantic import BaseModel


class MyModel(BaseModel):
    x: int

    def __init__(self, x: int | str):
        super().__init__(x=len(x) if isinstance(x, str) else x)

MyModel(x='test')

本文标签: pythonmypy with pydantic fieldvalidatorStack Overflow