我正在寻找一种“正确”的方法,以在Pydantic root_validator
装饰方法中进行严格的类型检查。
以下面的示例:在 validate_model
方法中,我希望能够使用MyPy严格的类型检查。由于 first_name
和 age
均已通过此方法进行验证和类型检查,因此我们可以假设 values ['first_name']
和值['age']
分别为'str'和'int'。
您可以看到#类型:ignore
“ hack”,我用来允许键入提示和停止mypy抱怨,但这很丑陋,如果我更改任何变量类型,可以创建错误。理想情况下, root_validator
装饰的方法将具有 value
参数与类 SimpleModel
本身相同,否则应该有一种简单的方法将 SimpleModel
转换为 typedDict
,因此我们可以在 validate_model
签名中使用它,例如:
def validate_model(cls,values:simpleModelTypedDict) - > 无论如何, SimpleModelTypedDict
,如果有人遇到了类似问题,请让我知道您如何解决它。
from pydantic import BaseModel, root_validator
class SimpleModel(BaseModel):
first_name: str
age: int
@root_validator(skip_on_failure=True)
def validate_model(cls, values: dict) -> dict:
"""checks there are no Bobs under 60 (sorry Bob!)"""
first_name: str = values.get("first_name") # type:ignore
age: int = values.get("age") # type:ignore
if first_name.lower() == "bob" and age < 60:
raise ValueError("No Bobs under 60")
return values
I'm looking for the "proper" way to have strict type checking within a pydantic root_validator
decorated method.
Take the example below: in the validate_model
method, I want to be able to use mypy strict type-checking. As both first_name
and age
have been validated and type-checked by the time this method is called, we can assume that values['first_name']
and values['age']
are of type 'str' and 'int' respectively.
You can see the # type:ignore
"hack" that I've used to allow type hinting and to stop mypy complaining, but it's pretty ugly, and could create bugs if I change any of the variable types. Ideally, a root_validator
decorated method would have the values
argument be of same type as the class SimpleModel
itself, or there should be a simple way to convert SimpleModel
into a TypedDict
, so we can use this in the validate_model
signature, for example:
def validate_model(cls, values: SimpleModelTypedDict) -> SimpleModelTypedDict
Anyway, if there is anyone out there that has run into a similar issue, please, let me know how you have tackled it.
from pydantic import BaseModel, root_validator
class SimpleModel(BaseModel):
first_name: str
age: int
@root_validator(skip_on_failure=True)
def validate_model(cls, values: dict) -> dict:
"""checks there are no Bobs under 60 (sorry Bob!)"""
first_name: str = values.get("first_name") # type:ignore
age: int = values.get("age") # type:ignore
if first_name.lower() == "bob" and age < 60:
raise ValueError("No Bobs under 60")
return values
发布评论
评论(1)
first_name
和age
的正确类型提示应分别为可选[str]
和可选[int]
。.get()
dict
的方法可以返回 none ,而值 dict of valivator将在那里是与提供的名称相对应的字段,或者是无效的:先前对该字段的验证失败。您使用skip_on_failure = true
,我相信它应该涵盖先前失败的验证的情况,但是.get()
的返回值仍然可以是none如果由于某种原因,您尝试获取不存在的字段。
使用该类型提示,如果
first_name
和age
变量是none
,则应验证您是否在尝试执行任何其他验证之前。完整示例:
The correct type hints for
first_name
andage
should beOptional[str]
andOptional[int]
, respectively. The.get()
method of adict
can returnNone
and thisvalues
dict of a validator will if there is no field that corresponds to the provided name or it is invalid: a validation failed previously for that field. You useskip_on_failure=True
and I believe it should cover the case of a previously failed validation, but the return value of.get()
can still beNone
if for some reason you try to get a field that does not exist.Using that type hint you should validate if the
first_name
andage
variables areNone
before trying to do any additional validations.Full example: