Pydantic Field正则编译超限错误,为何field_validator可正常使用?
原问题
我尝试定义一个Pydantic模型,其中字符串字段需匹配正则模式:^(\/[\w-]{1,255}){1,64}\/?$,用于验证类似/alphanumeric-slugs-no-longer-than-255-chars/separated-by-slashes/no-more-than-64-slugs/格式的表达式。
该模式需匹配1到64个slug,每个slug最长255字符,以斜杠分隔,验证后我会将字段按斜杠拆分并保存到数据库。
但当我通过Annotated字符串结合Field指定该正则模式时:
from typing import Annotated from pydantic import BaseModel, Field class MyModel(BaseModel): my_field: Annotated[str, Field(pattern=r"^(\/[\w-]{1,255}){1,64}\/?$")]
出现如下错误回溯:
pydantic_core._pydantic_core.SchemaError: Error building "function-after" validator: SchemaError: Error building "function-wrap" validator: SchemaError: Error building "model" validator: SchemaError: Error building "model-fields" validator: SchemaError: Field "full_path": SchemaError: Error building "default" validator: SchemaError: Error building "str" validator: SchemaError: Compiled regex exceeds size limit of 10485760 bytes.
我改用field_validator结合标准库的re.match实现正则验证:
import re from pydantic import BaseModel, field_validator class MyModel(BaseModel): my_field: str @field_validator("my_field") @classmethod def my_field_matches_regex(cls, v: str) -> str: if not re.match(r"^(\/[\w-]{1,255}){1,64}\/?$", v): raise ValueError("Invalid format, must match the regex pattern: ^(\/[\w-]{1,255}){1,64}\/?$") return v
这种方法可行,但我希望利用Field定义正则的简便性,疑惑为何Field的pattern属性会触发错误,而re.match却不会。
问题补充信息
- Python版本:
3.12 - Pydantic版本:
2.6.1
这是Rust抛出的编译时错误。查阅Pydantic文档可知,其默认regex_engine使用Rust正则实现。
原问题核心是询问为何Pydantic Field与re.match表现不同,原因在于二者使用了不同的正则引擎。
两种方案测试
我在正则测试工具上用同一模式^(\/[\w-]{1,255}){1,64}\/?$测试两个引擎,结果如下:
- Python引擎:通过15项测试,涵盖合法/非法字符、64个slug、超过64个slug、单slug最长255字符等场景,平均耗时0ms,最复杂测试耗时5ms,未出现灾难性回溯错误。
- Rust引擎:触发
engine error-Compiled regex exceeds size limit of 10485760 bytes.
额外测试
测试模式^(\/[\w-]+)+\/?$:
- Python引擎:通过10项测试,最长10000字符的测试耗时2ms,未出现灾难性回溯错误。
- Rust引擎:通过相同10项测试,最长字符测试耗时2ms。
测试模式^(\/[\w-]+){64}\/?$:
- Python引擎:通过13项测试,1项超64个slug的长测试失败,平均耗时0ms。
- Rust引擎:通过14项测试,但所有测试耗时增加(30-60ms),最复杂测试耗时超130ms。
问题初衷
我在使用Pydantic时未找到该错误的相关信息,希望通过此问题帮助遇到相同错误的用户理解原因及解决方法。
内容的提问来源于stack exchange,提问作者amoralesc
相关产品推荐
相关产品推荐

