If you use `@root_validator` with pre=False (the default) you MUST specify `skip_on_failure=True`

今天使用遇到一个pydantic 包的错误

File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/langchain/schema.py", line 140, in ChatGeneration
    def set_text(cls, values: Dict[str, Any]) -> Dict[str, Any]:
  File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/pydantic/deprecated/class_validators.py", line 222, in root_validator
    return root_validator()(*__args)  # type: ignore
  File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/pydantic/deprecated/class_validators.py", line 228, in root_validator
    raise PydanticUserError(
pydantic.errors.PydanticUserError: If you use `@root_validator` with pre=False (the default) you MUST specify `skip_on_failure=True`. Note that `@root_validator` is deprecated and should be replaced with `@model_validator`.
 

环境,python 3.10,pydantic 版本2.1.0,按照参考资料1 的说法,降低版本至1.10.x,但是整个程序(不是上面那一行)又会报如下这个错误

ImportError: cannot import name 'BeforeValidator' from 'pydantic' (/home/ubuntu/anaconda3/envs/memory/**/lib/python3.10/site-packages/pydantic/__init__.cpython-310-x86_64-linux-gnu.so)

而这个包BeforeValidator 只有在2.0以上才会有,所以两个版本都不行,那就改其中一个源码吧

第一个错误是使用langchain,版本0.0.144

 from langchain.llms import AzureOpenAI,OpenAIChat

此语句调用底层langchain/scheam.py, 如下的相关行

from abc import ABC, abstractmethod
from typing import Any, Dict, Generic, List, NamedTuple, Optional, TypeVar, Union

from pydantic import BaseModel, Extra, Field, root_validator


class Generation(BaseModel):
    """Output of a single generation."""

    text: str
    """Generated text output."""

    generation_info: Optional[Dict[str, Any]] = None
    """Raw generation info response from the provider"""
    """May include things like reason for finishing (e.g. in OpenAI)"""
    # TODO: add log probs
    
    
    
class ChatGeneration(Generation):
    """Output of a single generation."""

    text = ""
    message: BaseMessage

    @root_validator
    def set_text(cls, values: Dict[str, Any]) -> Dict[str, Any]:
        values["text"] = values["message"].content
        return values    

可以看到在类子类ChatGeneration中声明了一个装时器函数set_text,使用装饰器root_validator进行修饰的,而root_validator 在2.0版本以上已经属于deprecated,而且要求传参skip_on_failure=True才可以执行

root_validator的源码在**/pydantic/deprecated/class_validators.py里

def root_validator(
    *__args,
    pre: bool = False,
    skip_on_failure: bool = False,
    allow_reuse: bool = False,
) -> Any:
    """Decorate methods on a model indicating that they should be used to validate (and perhaps
    modify) data either before or after standard model parsing/validation is performed.

    Args:
        pre (bool, optional): Whether this validator should be called before the standard
            validators (else after). Defaults to False.
        skip_on_failure (bool, optional): Whether to stop validation and return as soon as a
            failure is encountered. Defaults to False.
        allow_reuse (bool, optional): Whether to track and raise an error if another validator
            refers to the decorated function. Defaults to False.

    Returns:
        Any: A decorator that can be used to decorate a function to be used as a root_validator.
    """
    warn(
        'Pydantic V1 style `@root_validator` validators are deprecated.'
        ' You should migrate to Pydantic V2 style `@model_validator` validators,'
        ' see the migration guide for more details',
        DeprecationWarning,
        stacklevel=2,
    )

    if __args:
        # Ensure a nice error is raised if someone attempts to use the bare decorator
        return root_validator()(*__args)  # type: ignore

    if allow_reuse is True:  # pragma: no cover
        warn(_ALLOW_REUSE_WARNING_MESSAGE, DeprecationWarning)
    mode: Literal['before', 'after'] = 'before' if pre is True else 'after'
    if pre is False and skip_on_failure is not True:
        raise PydanticUserError(
            'If you use `@root_validator` with pre=False (the default) you MUST specify `skip_on_failure=True`.'
            ' Note that `@root_validator` is deprecated and should be replaced with `@model_validator`.',
            code='root-validator-pre-skip',
        )

    wrap = partial(_decorators_v1.make_v1_generic_root_validator, pre=pre)

可以看到源码root_validator有多个入参,也可以看到报错的真正原因:pre为False 且skip_on_failure 也是False,pre 默认为False,skip_on_failure默认也是False ,所以报错

那么修改其中1个参数skip_on_failure,更改为True,在ChatGeneration的修饰器 @root_validator添加参数,修改为 @root_validator(skip_on_failure=True)

然后运行,报如下错误:

  File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/pydantic/_internal/_model_construction.py", line 98, in __new__
    private_attributes = inspect_namespace(
  File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/pydantic/_internal/_model_construction.py", line 337, in inspect_namespace
    raise PydanticUserError(
pydantic.errors.PydanticUserError: Field 'text' defined on a base class was overridden by a non-annotated attribute. All field definitions, including overrides, require a type annotation.
这个ChatGeneration 有个元素是text,它也要有类型约束,那就添加类型约束,改为

 text :str = ""

然后又报错:

name = Field(default="", const=True)

File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/pydantic/fields.py", line 741, in Field
    raise PydanticUserError('`const` is removed, use `Literal` instead', code='removed-kwargs')
pydantic.errors.PydanticUserError: `const` is removed, use `Literal` instead
 

然后再修改const 为Literal ,不过后面也报了不少错误,原因是2.0在1。0版本上做了很大改动,所以不建议在2.0版本直接进行修改,看了参考资料2 和3后,具体的解决方法如下:

当pydantic 只需要1.0版本即可满足要求时,果断从2.x的版本降为1.0的版本

但如果1.0版本和2.0版本都需要使用时,则需要安装2.0以上的版本,同时在使用1.0版本的程序或者源码上,添加pydantic.v1,如原语句from pydantic import Extra, root_validator,则需要改为from pydantic.v1 import Extra, root_validator,不过这个工作量可能很大,比较容易出错,最好的办法是避免2个版本同时使用,但尽管如此,这也是一种解决方法,可以试试

参考资料:

pydantic.errors.PydanticUserError: If you use `@root_validator`...._pydantic.errors.pydanticusererror: a non-annotated-优快云博客

2  https://github.com/run-llama/llama_index/issues/11401

3如何在不同的Pydantic版本中使用LangChain_pydantic版本如何从v2降回v1-优快云博客

07-07 16:09:47.323 dump_pyprocess_info [INFO] proc_data:{'15256': ['"python" D:\\DeviceTestTools\\device-tools-agent\\agent_main.py\r\r'], '11696': ['"python" D:\\DeviceTestTools\\tAgent\\product_execute\\app.py\r\r'], '6632': ['"D:\\DeviceTestTools\\python\\python.exe" "-c" "from multiprocessing.spawn import spawn_main; spawn_main(parent_pid=15256, pipe_handle=2276)" "--multiprocessing-fork"\r\r'], '16228': ['python D:\\Local\\DeviceTest\\20250707160716_c385\\icsv100_changan_c385\\devicetest\\agent\\ics_tep.py -p 18441\r\r']}.返回值是True 07-07 16:09:48.142 start_timer [INFO] 等待指令开启计时器 07-07 16:09:49.154 start_timer [INFO] 等待指令开启计时器 07-07 16:09:50.103 handle_message [INFO] handle_message recv uri: /tepmanager/hutaf-tc/v1/complete 07-07 16:09:50.103 report_end [INFO] --->> report end start 07-07 16:09:50.103 report_end [INFO] 框架异常上报用例块消息 07-07 16:09:50.118 report_end [INFO] response's headers: {'request_id': '1751875790104'} 07-07 16:09:50.118 report_end [INFO] response's body: {'retcode': '0', 'status': 'OK'} 07-07 16:09:50.165 start_timer [INFO] 等待指令开启计时器 07-07 16:09:50.949 dump_pyprocess_info [INFO] proc_data:{'15256': ['"python" D:\\DeviceTestTools\\device-tools-agent\\agent_main.py\r\r'], '11696': ['"python" D:\\DeviceTestTools\\tAgent\\product_execute\\app.py\r\r'], '6632': ['"D:\\DeviceTestTools\\python\\python.exe" "-c" "from multiprocessing.spawn import spawn_main; spawn_main(parent_pid=15256, pipe_handle=2276)" "--multiprocessing-fork"\r\r'], '16228': ['python D:\\Local\\DeviceTest\\20250707160716_c385\\icsv100_changan_c385\\devicetest\\agent\\ics_tep.py -p 18441\r\r']}.返回值是True 07-07 16:09:51.179 start_timer [INFO] 等待指令开启计时器 07-07 16:09:52.184 start_timer [INFO] 等待指令开启计时器 07-07 16:09:53.129 _ticcReportExecutorEnd [INFO] wait for ics_tep check finished!!! 07-07 16:09:53.129 _ticcReportExecutorEnd [INFO] ABNORMAL DEVICES: None 07-07 16:09:53.129 _ticcReportExecutorEnd [INFO] acquire lock 07-07 16:09:53.129 _ticcReportExecutorEnd [INFO] release lock 07-07 16:09:53.129 uploadTestCaseResult [INFO] acquire lock 07-07 16:09:53.130 uploadTestCaseResult [INFO] 测试用例:TC_RJSJ_TF001_FUNC001_006 07-07 16:09:53.130 uploadTestCaseResult [INFO] 执行结果:Blocked 07-07 16:09:53.130 uploadTestCaseResult [INFO] 失败原因:用例框架异常,环境配置解析适配,执行结束, If you use `@root_validator` with pre=False (the default) you MUST specify `skip_on_failure=True`. Note that `@root_validator` is deprecated and should be replaced with `@model_validator`. For further information visit https://errors.pydantic.dev/2.5/u/root-validator-pre-skip 07-07 16:09:53.130 notify_upload_log [INFO] D:\Local\ATLog\task_5569419\block_4909218091701174272_1\agent.log 路径是agent日志,不是用例日志。 07-07 16:09:53.130 _ticcReportCaseResult [INFO] ------------------------- uploadTestCaseResult Start 07-07 16:09:53.131 _ticcReportCaseResult [INFO] 上报用例的执行结果 07-07 16:09:53.132 _ticcReportCaseResult [INFO] upload result's url: https://apigw-cn-south.huawei.com/api/apigateway/tengwu/vtest/testcase-result 07-07 16:09:53.132 _ticcReportCaseResult [INFO] upload result's headers: {'request_id': '1751875793132'} 07-07 16:09:53.132 _ticcReportCaseResult [INFO] upload result's body: {'runTaskId': '5569419', 'blockId': '4909218091701174272', 'product': '253129109', 'number': 'TC_RJSJ_TF001_FUNC001_006', 'startTime': 1751875793131, 'finishTime': 1751875793131, 'result': '4', 'resultInfo': '用例框架异常,环境配置解析适配,执行结束, If you use `@root_validator` with pre=False (the default) you MUST specify `skip_on_failure=True`. Note that `@root_validator` is deprecated and should be replaced with `@model_validator`.\n\nFor further information visit https://errors.pydantic.dev/2.5/u/root-validator-pre-skip', 'uri': '/02ire0fuv8g/07190vfuhi848/07k7105qtqtf4/07k7105qtqtgc/07lb105qu1rlvu7g/07l9106lgd2p282o/07l9106lgd2pm82p/07l9106lgd2qn82r/07l9106lgd2s182v/', 'localLogPath': 'D:\\Local\\ATLog\\task_5569419\\block_4909218091701174272_1\\agent.log', 'executeTeIp': '10.39.85.66'} 07-07 16:09:53.191 start_timer [INFO] 等待指令开启计时器 07-07 16:09:53.373 _ticcReportCaseResult [INFO] upload result's response: (200, {'Server': 'API-Gateway', 'Date': 'Mon, 07 Jul 2025 08:09:53 GMT', 'Content-Length': '0', 'Connection': 'keep-alive', 'Trace-Id': 'e4379b6bcf00463d88635ddc5f3481ef', 'jalor-jwt-verify': 'true', 'Vary': 'Access-Control-Request-Headers', 'Gateway-Version': '6.6.8.0.RELEASE', 'Gateway-Env': 'tengwu-prod', 'Time-Trace': 'b60f1c58-42093528,pro-gw(184.198/55099)-apig1-Route2-lb2-jwt2-server(210.146/61339-200)15-sum15', 'X-Server-Process-Time': '0.0169', 'X-Upstream-Process-Time': '0.0169', 'X-ALB-SERVER': 'ALB'}, '') 07-07 16:09:53.373 _ticcReportCaseResult [INFO] 成功上报用例的执行结果 07-07 16:09:53.373 _ticcReportCaseResult [INFO] 还有0条用例待上报 07-07 16:09:53.373 _ticcReportCaseResult [INFO] ------------------------- uploadTestCaseResult End 07-07 16:09:53.374 notify_upload_other_log [INFO] 上传的本地日志路径是:D:\Local\ATLog\task_5569419\block_4909218091701174272_1\agent.log\TC_RJSJ_TF001_FUNC001_006 07-07 16:09:53.374 uploadTestCaseResult [INFO] 开启线程上传所有日志到NAS 07-07 16:09:53.374 notify_upload_other_log [INFO] D:\Local\ATLog\task_5569419\block_4909218091701174272_1\agent.log\TC_RJSJ_TF001_FUNC001_006,路径在执行机上不存在 07-07 16:09:53.374 uploadTestCaseResult [INFO] release lock 07-07 16:09:53.374 _ticcReportExecutorEnd [INFO] 最后一个用例的执行结果非PASS,再次检测设备状态,隔离异常设备 07-07 16:09:53.375 _ticcReportExecutorEnd [INFO] kill tep.py process, pid: 16228 07-07 16:09:53.474 _ticcReportExecutorEnd [INFO] kill tep.py process done 07-07 16:09:53.474 _ticcReportExecutorEnd [INFO] ------------------------- reportExecutorCmdEnd Start 07-07 16:09:53.680 _ticcReportExecutorEnd [INFO] report executor end's url: https://apigw-cn-south.huawei.com/api/apigateway/tengwu/vtest/testcase-block-result 07-07 16:09:53.680 _ticcReportExecutorEnd [INFO] report executor end's headers: {'request_id': '1751875793475'} 07-07 16:09:53.680 _ticcReportExecutorEnd [INFO] report executor end's body: {'runTaskId': '5569419', 'blockId': '4909218091701174272', 'environmentId': 'SDE-0aab505dd5184039a86ba5461c00211c', 'result': '0', 'failCaseReExecute': False} 07-07 16:09:53.680 _ticcReportExecutorEnd [INFO] response : (200, {'Server': 'API-Gateway', 'Date': 'Mon, 07 Jul 2025 08:09:53 GMT', 'Content-Length': '0', 'Connection': 'keep-alive', 'Trace-Id': 'dfcdf1a070c74aea9a95505dadb2b82d', 'jalor-jwt-verify': 'true', 'Vary': 'Access-Control-Request-Headers', 'Gateway-Version': '6.6.8.0.RELEASE', 'Gateway-Env': 'tengwu-prod', 'Time-Trace': 'b6d40755-42093544,pro-gw(184.198/55099)-apig3-Route4-lb4-jwt5-server(211.72/63402-200)8-sum9', 'X-Server-Process-Time': '0.0099', 'X-Upstream-Process-Time': '0.0099', 'X-ALB-SERVER': 'ALB'}, '') 07-07 16:09:53.680 _ticcReportExecutorEnd [INFO] ------------------------- reportExecutorCmdEnd End 07-07 16:09:53.680 _ticcReportExecutorEnd [INFO] ------------------------- 开始手动下发stop消息 07-07 16:09:53.680 _ticcReportExecutorEnd [INFO] 手动下发停止消息到flask's url: http://127.0.0.1:8810/api/agent/v1/testcase-block-deliver-stop 07-07 16:09:53.680 _ticcReportExecutorEnd [INFO] 手动下发停止消息到flask's headers: {'request_id': '1751875793680'} 07-07 16:09:53.680 _ticcReportExecutorEnd [INFO] 手动下发停止消息到flask's body: {'groupId': '10.39.85.66:8810', 'runTaskId': '5569419'} 07-07 16:09:53.963 pull_up_ics_tep [INFO] 待执行用例列表为空,任务下发用例已执行完毕,但是还有可能包含后置处理用例在执行! 07-07 16:09:53.963 pull_up_ics_tep [INFO] 已拉起框架,则以框架的report_end上报为准 07-07 16:09:53.963 pull_up_ics_tep [INFO] ics_tep stopped
最新发布
07-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值