You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pydantic的ImportString获取类实例遇Schema生成错误求解决

问题:Pydantic ImportString 泛型使用自定义类时触发Schema生成错误

问题复现

尝试使用Pydantic的ImportString类型导入指定对象实例,代码如下:

from __future__ import annotations

from pydantic.types import ImportString
from pydantic import Field, BaseModel
from typing import Annotated, Callable


class Foo:
    """A test class."""

    def __init__(self, name: str) -> None:
        self.name = name

    def __call__(self, name: str) -> str:
        """Call the foo class."""
        return f"hello {name}"


x = Foo("world")


def say_hello(name: str) -> str:
    """Say hello to a name."""
    return f"hello {name}"


def test_pydantic_ai_tool() -> None:
    """Test that the PydanticAiTool type can be used to validate a tool."""

    class Bar(BaseModel):
        foo: Annotated[
            ImportString[Callable[..., str]],
            Field(description="A tool that can be used in a pydantic-ai agent."),
        ]

    bar = Bar.model_validate(
        {
            "foo": "_tests.utils.types.test__pydantic_ai_tool.say_hello",
        },
    )
    assert bar.foo("world") == "hello world"
    assert bar.model_dump_json() == '{"foo":"_tests.utils.types.test__pydantic_ai_tool.say_hello"}'


def test_pydantic_ai_tool_two() -> None:
    """Test that the PydanticAiTool type can be used to validate a tool."""

    class Bar(BaseModel):
        foo: Annotated[
            ImportString[Foo],
            Field(description="A tool that can be used in a pydantic-ai agent."),
        ]

    bar = Bar.model_validate(
        {
            "foo": "_tests.utils.types.test__pydantic_ai_tool.x",
        },
    )
    assert bar.foo("world") == "hello world"
    assert bar.model_dump_json() == '{"foo": "_tests.utils.types.test__pydantic_ai_tool.x"}'

其中test_pydantic_ai_tool可正常运行,但test_pydantic_ai_tool_two执行时抛出错误:

E       pydantic.errors.PydanticSchemaGenerationError: Unable to generate pydantic-core schema for <class 'test__pydantic_ai_tool.Foo'>. Set `arbitrary_types_allowed=True` in the model_config to ignore this error or implement `__get_pydantic_core_schema__` on your type to fully support it.
E       
E       If you got this error by calling handler(<some type>) within `__get_pydantic_core_schema__` then you likely need to call `handler.generate_schema(<some type>)` since we do not call `__get_pydantic_core_schema__` on <some type> otherwise to avoid infinite recursion.
E       
E       For further information visit https://errors.pydantic.dev/2.10/u/schema-for-unknown-type

.venv/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py:513: PydanticSchemaGenerationError

期望效果:ImportString可导入路径对应的对象并验证其是否为指定类型的实例,序列化时仅返回导入字符串(如第一个测试中model_dump_json返回的是导入字符串而非目标类型的Schema)。


解决办法

方案1:在模型配置中启用arbitrary_types_allowed

自定义类Foo未实现Pydantic的Schema生成逻辑,因此需要在包含ImportString[Foo]的模型中开启任意类型允许,跳过对Foo的Schema检查。修改第二个测试中的Bar类:

class Bar(BaseModel):
    foo: Annotated[
        ImportString[Foo],
        Field(description="A tool that can be used in a pydantic-ai agent."),
    ]
    
    model_config = {"arbitrary_types_allowed": True}

方案2:为自定义类实现__get_pydantic_core_schema__

若不想全局启用任意类型允许,可在Foo类中添加Schema生成方法,让Pydantic能够识别该类型:

from pydantic_core import core_schema
from pydantic import GetCoreSchemaHandler

class Foo:
    """A test class."""

    def __init__(self, name: str) -> None:
        self.name = name

    def __call__(self, name: str) -> str:
        """Call the foo class."""
        return f"hello {name}"
    
    @classmethod
    def __get_pydantic_core_schema__(cls, source_type: type, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
        # 返回任意类型的Schema,也可根据需求自定义验证逻辑
        return core_schema.any_schema()

原因说明

第一个测试中Callable[..., str]是Pydantic原生支持的类型,内置了对应的Schema生成逻辑;而自定义类Foo不属于Pydantic默认支持的类型集合,因此在生成模型Schema时,Pydantic无法为其生成对应的核心Schema,从而抛出错误。ImportString在验证阶段会完成对象导入,但模型初始化时需要确认泛型参数的类型可被Schema化,因此需要让Pydantic能够处理Foo类型。


内容的提问来源于stack exchange,提问作者Tom McLean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 15:17:23