1111
1212from collections .abc import Generator
1313from dataclasses import dataclass , is_dataclass
14- from functools import cached_property
14+ from functools import cached_property , wraps
1515from typing import (
1616 TYPE_CHECKING ,
1717 Annotated ,
2525 Union ,
2626 overload ,
2727)
28- from typing_extensions import Self , get_args , get_origin , is_typeddict
28+ from typing_extensions import ParamSpec , Self , get_args , get_origin , is_typeddict
2929
3030from pydantic import VERSION , BaseModel
3131
3232from nonebot .typing import origin_is_annotated
3333
3434T = TypeVar ("T" )
35+ P = ParamSpec ("P" )
3536
3637PYDANTIC_V2 = int (VERSION .split ("." , 1 )[0 ]) == 2
3738
@@ -49,6 +50,7 @@ def __get_validators__(cls) -> Generator[Callable[..., Any], None, None]: ...
4950 "PYDANTIC_V2" ,
5051 "ConfigDict" ,
5152 "FieldInfo" ,
53+ "LegacyUnionField" ,
5254 "ModelField" ,
5355 "PydanticUndefined" ,
5456 "PydanticUndefinedType" ,
@@ -71,7 +73,7 @@ def __get_validators__(cls) -> Generator[Callable[..., Any], None, None]: ...
7173
7274
7375if PYDANTIC_V2 : # pragma: pydantic-v2
74- from pydantic import GetCoreSchemaHandler
76+ from pydantic import Field , GetCoreSchemaHandler
7577 from pydantic import TypeAdapter as TypeAdapter
7678 from pydantic import field_validator as field_validator
7779 from pydantic import model_validator as model_validator
@@ -94,6 +96,17 @@ def __get_validators__(cls) -> Generator[Callable[..., Any], None, None]: ...
9496 DEFAULT_CONFIG = ConfigDict (extra = "allow" , arbitrary_types_allowed = True )
9597 """Default config for validations"""
9698
99+ def _get_legacy_union_field (func : Callable [P , T ]) -> Callable [P , T ]:
100+ @wraps (func )
101+ def wrapper (* args : P .args , ** kwargs : P .kwargs ) -> T :
102+ kwargs ["union_mode" ] = "left_to_right"
103+ return func (* args , ** kwargs )
104+
105+ return wrapper
106+
107+ LegacyUnionField = _get_legacy_union_field (Field )
108+ LegacyUnionField .__doc__ = "Mark field to use legacy left to right union mode"
109+
97110 class FieldInfo (BaseFieldInfo ): # pyright: ignore[reportGeneralTypeIssues]
98111 """FieldInfo class with extra property for compatibility with pydantic v1"""
99112
@@ -292,6 +305,8 @@ class DEFAULT_CONFIG(ConfigDict):
292305 extra = Extra .allow
293306 arbitrary_types_allowed = True
294307
308+ from pydantic .fields import Field as LegacyUnionField
309+
295310 class FieldInfo (BaseFieldInfo ):
296311 def __init__ (self , default : Any = PydanticUndefined , ** kwargs : Any ):
297312 # preprocess default value to make it compatible with pydantic v2
0 commit comments