Pydantic v2.9 现已发布!您现在可以通过 PyPI 或您喜欢的包管理器安装它
pip install --upgrade pydantic
此版本包含了超过 25 位贡献者的工作成果!在这篇文章中,我们将介绍此版本的亮点。您可以在 GitHub 上查看完整的变更日志。
此版本包含显著的 性能改进、联合序列化改进 以及一些 新功能。
新功能
complex
数字支持
我们在 Pydantic 中增加了对 stdlib complex
数字的支持。对于验证,我们支持 complex
实例和可以 解析 为 complex
数字的字符串。
from pydantic import TypeAdapter
ta = TypeAdapter(complex)
complex_number = ta.validate_python('1+2j')
assert complex_number == complex(1, 2)
assert ta.dump_json(complex_number) == b'"1+2j"'
显式的 ZoneInfo
支持
Pydantic 现在显式支持 ZoneInfo
类型(在 Python v3.9+ 中)。这是一个使用新类型进行验证和序列化的示例
from pydantic import TypeAdapter
from zoneinfo import ZoneInfo
ta = TypeAdapter(ZoneInfo)
tz = ta.validate_python('America/Los_Angeles')
assert tz == ZoneInfo('America/Los_Angeles')
assert ta.dump_json(tz) == b'"America/Los_Angeles"'
感谢 @Youssefares 的贡献!有关新实现的更多详细信息,请参阅 #9896。
val_json_bytes
设置
新的 val_json_bytes
设置户户能够指定从 JSON 解码 bytes
数据时使用的编码。此设置与现有的 ser_json_bytes
结合使用,支持 bytes
数据的一致 JSON 往返。
例如
from pydantic import TypeAdapter, ConfigDict
ta = TypeAdapter(bytes, config=ConfigDict(ser_json_bytes='base64', val_json_bytes='base64'))
some_bytes = b'hello'
validated_bytes = ta.validate_python(some_bytes)
encoded_bytes = b'"aGVsbG8="'
assert ta.dump_json(validated_bytes) == encoded_bytes
# verifying round trip
# before we added support for val_json_bytes, the default encoding was 'utf-8' for validation, so this would fail
assert ta.validate_json(encoded_bytes) == validated_bytes
感谢 @josh-newman 的添加!您可以在 此处 查看完整的实现细节。
支持带有自定义验证器的 JSON schema
以前,当使用自定义验证器(如 BeforeValidator
或 field_validator
)时,无法自定义与相关字段/类型关联的 mode='validation'
JSON schema。
现在,您可以使用 json_schema_input_type
规范来自定义带有自定义验证器的字段的 JSON schema。例如
from typing import Any, Union
from pydantic_core import PydanticKnownError
from typing_extensions import Annotated
from pydantic import PlainValidator, TypeAdapter
def validate_maybe_int(v: Any) -> int:
if isinstance(v, int):
return v
elif isinstance(v, str):
try:
return int(v)
except ValueError:
...
raise PydanticKnownError('int_parsing')
ta = TypeAdapter(Annotated[int, PlainValidator(validate_maybe_int, json_schema_input_type=Union[int, str])])
print(ta.json_schema(mode='validation'))
# > {'anyOf': [{'type': 'integer'}, {'type': 'string'}]}
!!! note 您不能将此新功能与 mode='after'
验证器一起使用,因为在此上下文中自定义 mode='validation'
JSON schema 没有意义。
有关实现细节,请参阅 #10094。您可以在 API 文档中找到 json_schema_input_type
的文档,适用于所有支持所述规范的自定义验证器。
性能改进
在 v2.9.0 开发周期中,我们非常重视改进 Pydantic 的性能。具体来说,我们对模式构建过程进行了重大改进,从而加快了导入速度并减少了内存分配。
考虑以下用例:您在一个文件中(例如 models.py
)有大量 Pydantic 模型。您在另一个文件 (main.py
) 中导入其中一些模型。这对 Pydantic 用户来说是一种相对常见的模式。
对于上述情况,我们在导入速度方面实现了高达 10 倍的改进,并显着减少了临时内存分配,这对拥有大量模型的用户来说可能是一个巨大的胜利。
我们将讨论我们对模式构建过程所做的一些具体改进
- 将 pydantic 导入时间减少约 35%,请参阅 #10009 这涵盖了诸如
import pydantic
和from pydantic import BaseModel
之类的情况 - 通过优化热循环中的导入,将模式构建速度提高约 5%,请参阅 #10013
- 通过跳过命名空间缓存,将模式构建速度(和内存分配)提高高达 10 倍,请参阅 #10113
- 通过避免命名空间复制操作,减少临时内存分配,请参阅 #10267
我们计划在 v2.10 及更高版本中继续改进模式构建性能。您可以在上述 PR 中找到讨论的更多细节。
显著改进 / 修复
标记的 Union
序列化
Pydantic 以其标记的联合验证功能而闻名。在 pydantic/pydantic-core#1397 中,我们增加了对标记的联合序列化器的支持,这应该在使用标记的联合时做出更直观的序列化决策。我们还进行了一些相关的修复,例如改进 float | int
或 Decimal | float
联合的序列化选择。
将注解兼容性错误移至验证阶段
一般来说,在模式生成期间,Pydantic 在将验证器/约束逻辑应用于类型时非常慷慨。但在某些情况下可能会适得其反,当在运行时,很明显给定的验证器/约束与某些输入数据不兼容。在此版本中,我们为这些情况设计了一些更直观的错误消息,并将它们移动到验证(运行时)阶段,而不是在模式构建时在某些有效情况下失败。有关实现细节,请参阅 #9999
变更
破坏性变更:合并 dict
类型的 json_schema_extra
值,而不是覆盖
此更改不应影响任何内容,除非 json_schema_extra
的专门用法。话虽如此,如果您想复制旧的行为,请参阅 这些文档。
支持 $ref
键的同级键,从而删除 allOf
JSON schema 变通方法
任何受影响的 JSON 语法现在都有效,并且更简单!有关详细信息,请参阅 #10029。
弃用将 dict
传递给 Examples
类
这相对不言自明。有关更多详细信息,请参阅 #10181。此更改鼓励语法上有效的 JSON schema。
结论
我们很高兴地宣布 Pydantic v2.9.0 已经发布,它是迄今为止功能最丰富、速度最快的 Pydantic 版本。如果您有任何问题或反馈,请打开 GitHub 讨论。如果您遇到任何错误,请打开 GitHub issue。
感谢所有为实现此版本做出贡献的贡献者!我们特别要感谢以下个人为此次发布做出的重大贡献
Pydantic Logfire
如果您喜欢 Pydantic,您可能会非常喜欢 Pydantic Logfire,这是 Pydantic 团队构建的全新可观测性工具。您现在可以 试用 Logfire 免费版。如果您能加入 Pydantic Logfire Slack 并告诉我们您的想法,我们将不胜感激!