1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
from __future__ import annotations
import copy
from functools import cached_property # noqa: F401
from pathlib import Path
from typing import ( # noqa: F401
TYPE_CHECKING,
Any,
Callable,
Dict,
Protocol,
TypeVar,
runtime_checkable,
)
import pydantic
from packaging import version
from pydantic import BaseModel as _BaseModel
PYDANTIC_VERSION = version.parse(
pydantic.VERSION if isinstance(pydantic.VERSION, str) else str(pydantic.VERSION)
)
PYDANTIC_V2: bool = PYDANTIC_VERSION >= version.parse('2.0b3')
if TYPE_CHECKING:
from typing import Literal
from yaml import SafeLoader
def load_toml(path: Path) -> Dict[str, Any]: ...
else:
try:
from yaml import CSafeLoader as SafeLoader
except ImportError: # pragma: no cover
from yaml import SafeLoader
try:
import tomllib
def load_toml(path: Path) -> Dict[str, Any]:
with path.open('rb') as f:
return tomllib.load(f)
except ImportError:
import toml
def load_toml(path: Path) -> Dict[str, Any]:
return toml.load(path)
SafeLoaderTemp = copy.deepcopy(SafeLoader)
SafeLoaderTemp.yaml_constructors = copy.deepcopy(SafeLoader.yaml_constructors)
SafeLoaderTemp.add_constructor(
'tag:yaml.org,2002:timestamp',
SafeLoaderTemp.yaml_constructors['tag:yaml.org,2002:str'],
)
SafeLoader = SafeLoaderTemp
Model = TypeVar('Model', bound=_BaseModel)
def model_validator(
mode: Literal['before', 'after'] = 'after',
) -> Callable[[Callable[[Model, Any], Any]], Callable[[Model, Any], Any]]:
def inner(method: Callable[[Model, Any], Any]) -> Callable[[Model, Any], Any]:
if PYDANTIC_V2:
from pydantic import model_validator as model_validator_v2
return model_validator_v2(mode=mode)(method) # type: ignore
else:
from pydantic import root_validator
return root_validator(method, pre=mode == 'before') # type: ignore
return inner
def field_validator(
field_name: str,
*fields: str,
mode: Literal['before', 'after'] = 'after',
) -> Callable[[Any], Callable[[Model, Any], Any]]:
def inner(method: Callable[[Model, Any], Any]) -> Callable[[Model, Any], Any]:
if PYDANTIC_V2:
from pydantic import field_validator as field_validator_v2
return field_validator_v2(field_name, *fields, mode=mode)(method) # type: ignore
else:
from pydantic import validator
return validator(field_name, *fields, pre=mode == 'before')(method) # type: ignore
return inner
if PYDANTIC_V2:
from pydantic import ConfigDict as ConfigDict
else:
ConfigDict = dict # type: ignore
class BaseModel(_BaseModel):
if PYDANTIC_V2:
model_config = ConfigDict(strict=False)
|