基于Pydantic 2.7的自定义区间值验证类实现报错排查
解决Pydantic v2自定义区间验证类的问题
你的错误根源是__get_pydantic_core_schema__方法的签名不符合Pydantic v2的要求,该方法需要接收三个参数:self、source_type(当前被处理的类型)和handler(用于生成基础类型Schema的回调函数)。之前的定义缺少了source_type参数,导致Pydantic调用时参数不匹配,触发了类型错误。
以下是两种正确的类实现方案:
方案一:基础类实现
直接修正方法签名并完善Schema生成逻辑:
from typing import Any, Callable from pydantic_core import CoreSchema from pydantic import validate_call class ValueInInterval: def __init__( self, type_definition: Any, start: Any, end: Any, include_start: bool = True, include_end: bool = True, ): self.type_definition = type_definition self.start = start self.end = end self.include_start = include_start self.include_end = include_end def __get_pydantic_core_schema__( self, source_type: Any, handler: Callable[[Any], CoreSchema], ) -> CoreSchema: # 先获取基础类型的核心Schema base_schema = handler(self.type_definition) # 根据配置添加区间验证规则 if self.include_start: base_schema["ge"] = self.start else: base_schema["gt"] = self.start if self.include_end: base_schema["le"] = self.end else: base_schema["lt"] = self.end return base_schema @validate_call() def test_interval( value: ValueInInterval(type_definition=int, start=1, end=10), ): print(value) test_interval(value=1) # 执行成功,输出1 # test_interval(value=0) # 触发ValidationError,值小于区间下限
方案二:泛型类实现(推荐,类型提示更友好)
通过泛型让类型注解具备更好的IDE提示能力:
from typing import Any, Callable, Generic, TypeVar from pydantic_core import CoreSchema from pydantic import validate_call T = TypeVar('T') class ValueInInterval(Generic[T]): def __init__( self, start: T, end: T, include_start: bool = True, include_end: bool = True, ): self.start = start self.end = end self.include_start = include_start self.include_end = include_end self.type_definition = T def __get_pydantic_core_schema__( self, source_type: Any, handler: Callable[[Any], CoreSchema], ) -> CoreSchema: base_schema = handler(self.type_definition) if self.include_start: base_schema["ge"] = self.start else: base_schema["gt"] = self.start if self.include_end: base_schema["le"] = self.end else: base_schema["lt"] = self.end return base_schema @validate_call() def test_interval( value: ValueInInterval[int](start=1, end=10), ): print(value) test_interval(value=1) # 执行成功,输出1 # test_interval(value=11) # 触发ValidationError,值大于区间上限
关键修正点说明
- 修正方法签名:添加
source_type参数,符合Pydantic v2对自定义类型Schema生成方法的要求 - 正确生成基础Schema:通过
handler回调获取传入类型的核心验证规则,再叠加区间验证逻辑 - 泛型优化:方案二通过泛型让IDE能识别参数的实际类型(如
int),提升开发体验
内容的提问来源于stack exchange,提问作者Jacob Ayers
相关产品推荐
相关产品推荐

