Pydantic 校验 namedtuple 报缺少 y,检查 Sequence 的重建路径
把 namedtuple 当成泛用 Sequence 校验时,旧重建路径可能把整个列表作为一个构造参数。正式 2.14.1 已含 namedtuple 专用展开;固定结构也可直接声明 NamedTuple schema。
TypeAdapter(Sequence[int]) 接收一个两字段 namedtuple,输入值都能转成整数,最后却报 Point.__new__() missing 1 required positional argument: 'y'。若只有一个字段,还可能不报错,却把原来的标量变成列表。
这要检查验证完成后的容器重建,而不只是输入元素。受影响的逻辑先把内容验证成列表,再调用 value_type(validated_list);普通 tuple 可以接收一个可迭代对象,namedtuple 的构造函数却要求按字段分别传入位置参数。
先确认实际安装的实现
正式 Pydantic 2.14.1 的 sequence_validator 已有 namedtuple 专用分支,使用 value_type(*validated_list),不再走上述单参数猜测。这个结论来自具体正式包的实现,不代表所有旧版本或任意第三方重写的适配器都已同步修好。
若环境仍有相同错误,核对解释器真正加载的 Pydantic 版本与依赖锁。不要只看另外一个终端显示的版本,也不要把开发版的问题记录理解成当前正式版仍必然失败。
固定结构可以直接声明 NamedTuple
数据本来就是固定的 x、y,比起泛用 Sequence,直接为它建立明确的 schema 更容易保留契约:
from typing import NamedTuple
from pydantic import TypeAdapter
class Point(NamedTuple):
x: int
y: int
adapter = TypeAdapter(Point)
point = adapter.validate_python(("1", "2"))
目标结果是字段值分别为整数的 Point(x=1, y=2)。这里验证的是特定类型、固定字段数量,不是“任何长度的整数序列”。如果业务原来确实接受任意 Sequence,不能为了绕过异常就把接口无条件改成两个元素。
暂时无法更换受影响依赖时,也可以在应用明确的边界只返回验证后的普通列表或 tuple,但这会改变原容器类型,必须得到调用方契约支持。不能把整个验证结果强行塞到 namedtuple 的第一个字段,让后续代码在更远处才发现结构变化。
复核同时覆盖零、一、二字段 namedtuple、普通 tuple 与列表,以及元素验证失败的情况。成功不只是没有 TypeError,还应核对字段数量、每个值的类型和容器类型;尤其要保留一字段情况,避免静默的列表嵌套漏过检查。


