File: util.py

package info (click to toggle)
python-datamodel-code-generator 0.26.4-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 712 kB
  • sloc: python: 9,525; makefile: 14
file content (106 lines) | stat: -rw-r--r-- 2,829 bytes parent folder | download
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)