Feature: 优化 pydantic 兼容函数 model_dumptype_validate_json (#2579)

Co-authored-by: Ju4tCode <42488585+yanyongyu@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
MingxuanGame 2024-02-17 23:18:00 +08:00 committed by GitHub
parent fbb8320a25
commit a830346545
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 58 additions and 4 deletions

View File

@ -16,6 +16,7 @@ from typing import (
Dict,
List,
Type,
Union,
TypeVar,
Callable,
Optional,
@ -54,6 +55,7 @@ __all__ = (
"model_config",
"model_dump",
"type_validate_python",
"type_validate_json",
"custom_validation",
)
@ -195,13 +197,27 @@ if PYDANTIC_V2: # pragma: pydantic-v2
include: Optional[Set[str]] = None,
exclude: Optional[Set[str]] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
) -> Dict[str, Any]:
return model.model_dump(include=include, exclude=exclude, by_alias=by_alias)
return model.model_dump(
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
)
def type_validate_python(type_: Type[T], data: Any) -> T:
"""Validate data with given type."""
return TypeAdapter(type_).validate_python(data)
def type_validate_json(type_: Type[T], data: Union[str, bytes]) -> T:
"""Validate JSON with given type."""
return TypeAdapter(type_).validate_json(data)
def __get_pydantic_core_schema__(
cls: Type["_CustomValidationClass"],
source_type: Any,
@ -226,7 +242,7 @@ if PYDANTIC_V2: # pragma: pydantic-v2
else: # pragma: pydantic-v1
from pydantic import Extra
from pydantic import parse_obj_as
from pydantic import parse_obj_as, parse_raw_as
from pydantic import BaseConfig as PydanticConfig
from pydantic.fields import FieldInfo as BaseFieldInfo
from pydantic.fields import ModelField as BaseModelField
@ -341,13 +357,27 @@ else: # pragma: pydantic-v1
include: Optional[Set[str]] = None,
exclude: Optional[Set[str]] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
) -> Dict[str, Any]:
return model.dict(include=include, exclude=exclude, by_alias=by_alias)
return model.dict(
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
)
def type_validate_python(type_: Type[T], data: Any) -> T:
"""Validate data with given type."""
return parse_obj_as(type_, data)
def type_validate_json(type_: Type[T], data: Union[str, bytes]) -> T:
"""Validate JSON with given type."""
return parse_raw_as(type_, data)
def custom_validation(class_: Type["CVC"]) -> Type["CVC"]:
"""Do nothing in pydantic v1"""
return class_

View File

@ -1,4 +1,4 @@
from typing import Any
from typing import Any, Optional
from dataclasses import dataclass
import pytest
@ -11,6 +11,7 @@ from nonebot.compat import (
PydanticUndefined,
model_dump,
custom_validation,
type_validate_json,
type_validate_python,
)
@ -66,3 +67,26 @@ async def test_custom_validation():
assert type_validate_python(TestModel, {"test": 1}) == TestModel(test=1)
assert called == [1, 2]
@pytest.mark.asyncio
async def test_validate_json():
class TestModel(BaseModel):
test1: int
test2: str
test3: bool
test4: dict
test5: list
test6: Optional[int]
assert type_validate_json(
TestModel,
"{"
' "test1": 1,'
' "test2": "2",'
' "test3": true,'
' "test4": {},'
' "test5": [],'
' "test6": null'
"}",
) == TestModel(test1=1, test2="2", test3=True, test4={}, test5=[], test6=None)