ialdev-core 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- iad/core/__init__.py +9 -0
- iad/core/array.py +1961 -0
- iad/core/binary.py +377 -0
- iad/core/cache.py +903 -0
- iad/core/codetools.py +203 -0
- iad/core/datatools.py +671 -0
- iad/core/docs/locators.ipynb +754 -0
- iad/core/dotstyle.py +99 -0
- iad/core/env.py +271 -0
- iad/core/events.py +650 -0
- iad/core/filesproc.py +1046 -0
- iad/core/fnctools.py +390 -0
- iad/core/label.py +240 -0
- iad/core/logs.py +182 -0
- iad/core/nptools.py +449 -0
- iad/core/one_dark.puml +881 -0
- iad/core/param/__init__.py +17 -0
- iad/core/param/confargparse.py +55 -0
- iad/core/param/paramaze.py +339 -0
- iad/core/param/tbox.py +277 -0
- iad/core/paths.py +563 -0
- iad/core/pdtools.py +2570 -0
- iad/core/pydantools/__init__.py +5 -0
- iad/core/pydantools/fixed_pydantic_yaml/__init__.py +32 -0
- iad/core/pydantools/fixed_pydantic_yaml/compat/__init__.py +0 -0
- iad/core/pydantools/fixed_pydantic_yaml/compat/hacks.py +76 -0
- iad/core/pydantools/fixed_pydantic_yaml/compat/old_enums.py +37 -0
- iad/core/pydantools/fixed_pydantic_yaml/compat/representers.py +92 -0
- iad/core/pydantools/fixed_pydantic_yaml/compat/types.py +122 -0
- iad/core/pydantools/fixed_pydantic_yaml/compat/yaml_lib.py +104 -0
- iad/core/pydantools/fixed_pydantic_yaml/ext/__init__.py +1 -0
- iad/core/pydantools/fixed_pydantic_yaml/ext/semver.py +152 -0
- iad/core/pydantools/fixed_pydantic_yaml/ext/versioned_model.py +113 -0
- iad/core/pydantools/fixed_pydantic_yaml/main.py +30 -0
- iad/core/pydantools/fixed_pydantic_yaml/mixin.py +281 -0
- iad/core/pydantools/fixed_pydantic_yaml/model.py +20 -0
- iad/core/pydantools/fixed_pydantic_yaml/py.typed +1 -0
- iad/core/pydantools/fixed_pydantic_yaml/version.py +1 -0
- iad/core/pydantools/models.py +560 -0
- iad/core/regexp.py +348 -0
- iad/core/short.py +308 -0
- iad/core/strings.py +635 -0
- iad/core/unc_panda.py +270 -0
- iad/core/units.py +58 -0
- iad/core/wrap.py +420 -0
- ialdev_core-0.1.0.dist-info/METADATA +73 -0
- ialdev_core-0.1.0.dist-info/RECORD +48 -0
- ialdev_core-0.1.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
from typing import Optional, Tuple, Type
|
|
3
|
+
|
|
4
|
+
from pydantic.v1 import validator
|
|
5
|
+
|
|
6
|
+
from .semver import SemVer
|
|
7
|
+
from ..model import YamlModel
|
|
8
|
+
|
|
9
|
+
__all__ = ["VersionedYamlModel"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _chk_between(v, lo=None, hi=None):
|
|
13
|
+
if v is None:
|
|
14
|
+
return
|
|
15
|
+
if (hi is not None) and (v > hi):
|
|
16
|
+
raise ValueError(f"Default version higher than maximum: {v} > {hi}")
|
|
17
|
+
if (lo is not None) and (v < lo):
|
|
18
|
+
raise ValueError(f"Default version lower than minimum: {v} < {lo}")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _get_minmax_robust(
|
|
22
|
+
cls: Type["VersionedYamlModel"],
|
|
23
|
+
) -> Tuple[Optional[SemVer], Optional[SemVer]]:
|
|
24
|
+
min_, max_ = None, None
|
|
25
|
+
for supcls in cls.mro():
|
|
26
|
+
Config = getattr(supcls, "Config", None)
|
|
27
|
+
if Config is not None:
|
|
28
|
+
if min_ is None:
|
|
29
|
+
min_ = getattr(Config, "min_version", None)
|
|
30
|
+
if max_ is None:
|
|
31
|
+
max_ = getattr(Config, "max_version", None)
|
|
32
|
+
return min_, max_
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class VersionedYamlModel(YamlModel):
|
|
36
|
+
"""YAML model with versioning support.
|
|
37
|
+
|
|
38
|
+
Usage
|
|
39
|
+
-----
|
|
40
|
+
Inherit from this class, and set a Config class with attributes
|
|
41
|
+
`min_version` and/or `max_version`:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
class MyModel(VersionedYamlModel):
|
|
45
|
+
class Config:
|
|
46
|
+
min_version = "1.0.0"
|
|
47
|
+
|
|
48
|
+
foo: str = "bar"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
By default, the minimum version is "0.0.0" and the maximum is unset.
|
|
52
|
+
This pattern enables you to more easily version your YAML files and
|
|
53
|
+
protect against accidentally using older (or newer) configuration file formats.
|
|
54
|
+
|
|
55
|
+
Notes
|
|
56
|
+
-----
|
|
57
|
+
By default, a validator checks that the "version" field is between
|
|
58
|
+
`Config.min_version` and `Config.max_version`, if those are not None.
|
|
59
|
+
|
|
60
|
+
It's probably best not to even set the `version` field by hand, but rather
|
|
61
|
+
in your configuration.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
version: SemVer
|
|
65
|
+
|
|
66
|
+
def __init_subclass__(cls) -> None:
|
|
67
|
+
# Check Config class types
|
|
68
|
+
Config = getattr(cls, "Config", None)
|
|
69
|
+
if Config is not None:
|
|
70
|
+
# check one field
|
|
71
|
+
minv = getattr(Config, "min_version", None)
|
|
72
|
+
if minv is not None:
|
|
73
|
+
if not isinstance(minv, SemVer):
|
|
74
|
+
setattr(Config, "min_version", SemVer(minv))
|
|
75
|
+
# check other field
|
|
76
|
+
maxv = getattr(Config, "max_version", None)
|
|
77
|
+
if maxv is not None:
|
|
78
|
+
if not isinstance(maxv, SemVer):
|
|
79
|
+
setattr(Config, "max_version", SemVer(maxv))
|
|
80
|
+
|
|
81
|
+
# Check ranges
|
|
82
|
+
min_, max_ = _get_minmax_robust(cls)
|
|
83
|
+
if (min_ is not None) and (max_ is not None) and (min_ > max_):
|
|
84
|
+
raise ValueError(
|
|
85
|
+
f"Minimum version higher than maximum: {min_!r} > {max_!r}"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# Check the default value of the "version" field
|
|
89
|
+
fld = cls.__fields__["version"]
|
|
90
|
+
d = fld.default
|
|
91
|
+
if d is None:
|
|
92
|
+
pass
|
|
93
|
+
else:
|
|
94
|
+
_chk_between(d, lo=min_, hi=max_)
|
|
95
|
+
warnings.warn(
|
|
96
|
+
f"Recommended to have `version` be required, but set default {d!r}",
|
|
97
|
+
UserWarning,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
if not issubclass(fld.type_, SemVer):
|
|
101
|
+
raise TypeError(
|
|
102
|
+
f"Field type for `version` must be SemVer, got {fld.type_!r}"
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
@validator("version", always=True)
|
|
106
|
+
def _check_semver(cls, v):
|
|
107
|
+
min_, max_ = _get_minmax_robust(cls)
|
|
108
|
+
_chk_between(v, lo=min_, hi=max_)
|
|
109
|
+
return v
|
|
110
|
+
|
|
111
|
+
class Config:
|
|
112
|
+
min_version = SemVer("0.0.0")
|
|
113
|
+
max_version = None
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""YAML-enabled Pydantic models."""
|
|
2
|
+
|
|
3
|
+
__all__ = [
|
|
4
|
+
"__version__",
|
|
5
|
+
"yaml",
|
|
6
|
+
"yaml_safe_dump",
|
|
7
|
+
"yaml_safe_load",
|
|
8
|
+
"YamlEnum",
|
|
9
|
+
"YamlInt",
|
|
10
|
+
"YamlIntEnum",
|
|
11
|
+
"YamlStr",
|
|
12
|
+
"YamlStrEnum",
|
|
13
|
+
"YamlModel",
|
|
14
|
+
"YamlModelMixin",
|
|
15
|
+
"YamlModelMixinConfig",
|
|
16
|
+
"SemVer",
|
|
17
|
+
"VersionedYamlModel",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
from .compat.old_enums import YamlEnum
|
|
21
|
+
from .compat.hacks import inject_all as _inject_yaml_hacks
|
|
22
|
+
from .compat.types import YamlInt, YamlIntEnum, YamlStr, YamlStrEnum
|
|
23
|
+
from .compat.yaml_lib import yaml, yaml_safe_dump, yaml_safe_load
|
|
24
|
+
from .ext.semver import SemVer
|
|
25
|
+
from .ext.versioned_model import VersionedYamlModel
|
|
26
|
+
from .mixin import YamlModelMixin, YamlModelMixinConfig
|
|
27
|
+
from .model import YamlModel
|
|
28
|
+
from .version import __version__
|
|
29
|
+
|
|
30
|
+
_inject_yaml_hacks()
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
"""Module to define the YamlModelMixin."""
|
|
2
|
+
|
|
3
|
+
from typing_extensions import Literal
|
|
4
|
+
import warnings
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import (
|
|
7
|
+
TYPE_CHECKING,
|
|
8
|
+
Any,
|
|
9
|
+
Callable,
|
|
10
|
+
ClassVar,
|
|
11
|
+
Optional,
|
|
12
|
+
Type,
|
|
13
|
+
TypeVar,
|
|
14
|
+
Union,
|
|
15
|
+
cast,
|
|
16
|
+
no_type_check,
|
|
17
|
+
)
|
|
18
|
+
from pydantic.v1 import BaseModel, ValidationError
|
|
19
|
+
from pydantic.v1.error_wrappers import ErrorWrapper
|
|
20
|
+
from pydantic.v1.parse import Protocol, load_file, load_str_bytes
|
|
21
|
+
from pydantic.v1.main import ROOT_KEY, ModelMetaclass, BaseConfig
|
|
22
|
+
from pydantic.v1.types import StrBytes
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from pydantic.v1.typing import DictStrAny, AbstractSetIntStr, MappingIntStrAny
|
|
26
|
+
|
|
27
|
+
Model = TypeVar("Model", bound="BaseModel")
|
|
28
|
+
|
|
29
|
+
from .compat.yaml_lib import yaml_safe_dump, yaml_safe_load
|
|
30
|
+
|
|
31
|
+
ExtendedProto = Union[Protocol, Literal["yaml"]]
|
|
32
|
+
|
|
33
|
+
YamlStyle = Union[
|
|
34
|
+
None,
|
|
35
|
+
Literal[""],
|
|
36
|
+
Literal['"'],
|
|
37
|
+
Literal["'"],
|
|
38
|
+
Literal["|"],
|
|
39
|
+
Literal[">"],
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def is_yaml_requested(
|
|
44
|
+
content_type: Optional[str] = None,
|
|
45
|
+
proto: Optional[ExtendedProto] = None,
|
|
46
|
+
path_suffix: Optional[str] = None,
|
|
47
|
+
) -> bool:
|
|
48
|
+
"""Checks whether YAML is requested by the user, depending on params."""
|
|
49
|
+
is_yaml = False
|
|
50
|
+
if content_type is not None:
|
|
51
|
+
is_yaml = ("yaml" in content_type) or ("yml" in content_type)
|
|
52
|
+
if proto is not None:
|
|
53
|
+
is_yaml = is_yaml or (proto == "yaml")
|
|
54
|
+
if path_suffix is not None:
|
|
55
|
+
is_yaml = is_yaml or (path_suffix in [".yaml", ".yml"])
|
|
56
|
+
return is_yaml
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class YamlModelMixinConfig:
|
|
60
|
+
"""Additional configuration for YamlModelMixin."""
|
|
61
|
+
|
|
62
|
+
yaml_loads: Callable[[str], Any] = yaml_safe_load # type: ignore
|
|
63
|
+
yaml_dumps: Callable[..., str] = yaml_safe_dump # type: ignore
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class YamlModelMixin(metaclass=ModelMetaclass):
|
|
67
|
+
"""Mixin to add YAML compatibility to your class.
|
|
68
|
+
|
|
69
|
+
Usage
|
|
70
|
+
-----
|
|
71
|
+
Inherit from this and a `pydantic.BaseModel` or a subclass, like this:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
class MyBaseType(BaseModel):
|
|
75
|
+
my_field: str = "default"
|
|
76
|
+
|
|
77
|
+
class MyExtType(YamlModelMixin, MyBaseType):
|
|
78
|
+
other_field: int = 42
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`YamlModelMixin` *must* be *before* any class that inherits from
|
|
82
|
+
`pydantic.BaseModel` due to issues with the method resolution order.
|
|
83
|
+
|
|
84
|
+
You can now use `MyExtType().yaml()` to dump the class values (default here)
|
|
85
|
+
to a YAML string.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
if TYPE_CHECKING:
|
|
89
|
+
__custom_root_type__: ClassVar[bool] = False
|
|
90
|
+
__config__: ClassVar[Type[BaseConfig]] = YamlModelMixinConfig # type: ignore
|
|
91
|
+
|
|
92
|
+
@no_type_check
|
|
93
|
+
def __init_subclass__(cls, **_) -> None:
|
|
94
|
+
super().__init_subclass__()
|
|
95
|
+
|
|
96
|
+
# Set the config class
|
|
97
|
+
cfg: Type[YamlModelMixinConfig] = cls.__config__
|
|
98
|
+
if not issubclass(cfg, YamlModelMixinConfig):
|
|
99
|
+
class T(cfg, YamlModelMixinConfig):
|
|
100
|
+
pass
|
|
101
|
+
|
|
102
|
+
T.__doc__ = cfg.__doc__
|
|
103
|
+
T.__name__ = cfg.__name__
|
|
104
|
+
T.__qualname__ = cfg.__qualname__
|
|
105
|
+
|
|
106
|
+
cls.__config__ = T
|
|
107
|
+
|
|
108
|
+
def yaml(
|
|
109
|
+
self,
|
|
110
|
+
*,
|
|
111
|
+
include: Union["AbstractSetIntStr", "MappingIntStrAny", None] = None,
|
|
112
|
+
exclude: Union["AbstractSetIntStr", "MappingIntStrAny", None] = None,
|
|
113
|
+
by_alias: bool = False,
|
|
114
|
+
skip_defaults: Optional[bool] = None,
|
|
115
|
+
exclude_unset: bool = False,
|
|
116
|
+
exclude_defaults: bool = False,
|
|
117
|
+
exclude_none: bool = False,
|
|
118
|
+
sort_keys: bool = False,
|
|
119
|
+
default_flow_style: Optional[bool] = False,
|
|
120
|
+
default_style: YamlStyle = None,
|
|
121
|
+
indent: Optional[bool] = None,
|
|
122
|
+
encoding: Optional[str] = None,
|
|
123
|
+
**kwargs,
|
|
124
|
+
) -> str:
|
|
125
|
+
"""Generate a YAML representation of the model.
|
|
126
|
+
|
|
127
|
+
Parameters
|
|
128
|
+
----------
|
|
129
|
+
include, exclude
|
|
130
|
+
Fields to include or exclude. See `dict()`.
|
|
131
|
+
by_alias : bool
|
|
132
|
+
Whether to use aliases instead of declared names. Default is False.
|
|
133
|
+
skip_defaults, exclude_unset, exclude_defaults, exclude_none
|
|
134
|
+
Arguments as per `BaseModel.dict()`.
|
|
135
|
+
sort_keys : bool
|
|
136
|
+
If True, will sort the keys in alphanumeric order for dictionaries.
|
|
137
|
+
Default is False, which will dump in the field definition order.
|
|
138
|
+
default_flow_style : bool or None
|
|
139
|
+
Whether to use the "flow" style in the dumper. By default, this is False,
|
|
140
|
+
which uses the "block" style (probably the most familiar to users).
|
|
141
|
+
default_style : {None, "", "'", '"', "|", ">"}
|
|
142
|
+
This is the default style for quoting strings, used by `ruamel.yaml` dumper.
|
|
143
|
+
Default is None, which varies the style based on line length.
|
|
144
|
+
indent, encoding, kwargs
|
|
145
|
+
Additional arguments for the dumper.
|
|
146
|
+
"""
|
|
147
|
+
data: "DictStrAny" = self.dict( # type: ignore
|
|
148
|
+
include=include,
|
|
149
|
+
exclude=exclude,
|
|
150
|
+
by_alias=by_alias,
|
|
151
|
+
skip_defaults=skip_defaults,
|
|
152
|
+
exclude_unset=exclude_unset,
|
|
153
|
+
exclude_defaults=exclude_defaults,
|
|
154
|
+
exclude_none=exclude_none,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
if self.__custom_root_type__:
|
|
158
|
+
data = data[ROOT_KEY]
|
|
159
|
+
warnings.warn(
|
|
160
|
+
"Explicit custom root behavior not yet implemented for pydantic_yaml."
|
|
161
|
+
" This may not work as expected. If so, please create a GitHub issue:"
|
|
162
|
+
" https://github.com/NowanIlfideme/pydantic-yaml/issues/new"
|
|
163
|
+
)
|
|
164
|
+
cfg = cast(YamlModelMixinConfig, self.__config__)
|
|
165
|
+
return cfg.yaml_dumps(
|
|
166
|
+
data,
|
|
167
|
+
sort_keys=sort_keys,
|
|
168
|
+
default_flow_style=default_flow_style,
|
|
169
|
+
default_style=default_style,
|
|
170
|
+
encoding=encoding,
|
|
171
|
+
indent=indent,
|
|
172
|
+
**kwargs,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
@no_type_check
|
|
176
|
+
@classmethod
|
|
177
|
+
def parse_raw(
|
|
178
|
+
cls: Type["Model"],
|
|
179
|
+
b: StrBytes,
|
|
180
|
+
*,
|
|
181
|
+
content_type: str = "application/yaml", # This is a reasonable default, right?
|
|
182
|
+
encoding: str = "utf-8",
|
|
183
|
+
proto: ExtendedProto = None,
|
|
184
|
+
allow_pickle: bool = False,
|
|
185
|
+
) -> "Model":
|
|
186
|
+
# NOTE: Type checking this function is a PITA, because we're overriding
|
|
187
|
+
# BaseModel.parse_raw, but not inheriting it due to the MRO problem!
|
|
188
|
+
|
|
189
|
+
# Check whether we're specifically asked to parse YAML
|
|
190
|
+
is_yaml = is_yaml_requested(content_type=content_type, proto=proto)
|
|
191
|
+
|
|
192
|
+
# Note that JSON is a subset of the YAML 1.2 spec, so we should be OK
|
|
193
|
+
# even if JSON is passed. It will be slower, however.
|
|
194
|
+
if is_yaml:
|
|
195
|
+
try:
|
|
196
|
+
cfg = cast(YamlModelMixinConfig, cls.__config__)
|
|
197
|
+
obj = cfg.yaml_loads(b)
|
|
198
|
+
except RecursionError as e:
|
|
199
|
+
raise ValueError(
|
|
200
|
+
"YAML files with recursive references are unsupported."
|
|
201
|
+
) from e
|
|
202
|
+
except ValidationError:
|
|
203
|
+
raise
|
|
204
|
+
except Exception as e:
|
|
205
|
+
raise ValidationError([ErrorWrapper(e, loc=ROOT_KEY)], cls) from e
|
|
206
|
+
else:
|
|
207
|
+
obj = load_str_bytes(
|
|
208
|
+
b,
|
|
209
|
+
proto=proto,
|
|
210
|
+
content_type=content_type,
|
|
211
|
+
encoding=encoding,
|
|
212
|
+
allow_pickle=allow_pickle,
|
|
213
|
+
json_loads=cls.__config__.json_loads,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
return obj
|
|
217
|
+
|
|
218
|
+
@no_type_check
|
|
219
|
+
@classmethod
|
|
220
|
+
def parse_file(
|
|
221
|
+
cls: Type["Model"],
|
|
222
|
+
path: Union[str, Path],
|
|
223
|
+
*,
|
|
224
|
+
content_type: str = None,
|
|
225
|
+
encoding: str = "utf-8",
|
|
226
|
+
proto: ExtendedProto = None,
|
|
227
|
+
allow_pickle: bool = False,
|
|
228
|
+
) -> "Model":
|
|
229
|
+
obj = cls.parse_file_to_dict(path, content_type=content_type, encoding=encoding,
|
|
230
|
+
proto=proto, allow_pickle=allow_pickle)
|
|
231
|
+
res = cls.parse_obj(obj) # type: ignore
|
|
232
|
+
return cast("Model", res)
|
|
233
|
+
|
|
234
|
+
@classmethod
|
|
235
|
+
def parse_file_to_dict(cls, path: Union[str, Path],
|
|
236
|
+
*,
|
|
237
|
+
content_type: str = None,
|
|
238
|
+
encoding: str = "utf-8",
|
|
239
|
+
proto: ExtendedProto = None,
|
|
240
|
+
allow_pickle: bool = False):
|
|
241
|
+
path = Path(path)
|
|
242
|
+
# Assume YAML based on the file name, so `parse_raw()` works well below
|
|
243
|
+
if (content_type is None) and (path.suffix in [".yml", ".yaml"]):
|
|
244
|
+
content_type = "application/yaml"
|
|
245
|
+
# Check whether we're specifically asked to parse YAML
|
|
246
|
+
is_yaml = is_yaml_requested(
|
|
247
|
+
content_type=content_type, proto=proto, path_suffix=path.suffix
|
|
248
|
+
)
|
|
249
|
+
# The first code path explicitly checks YAML compatibility.
|
|
250
|
+
# We offload the rest to Pydantic.
|
|
251
|
+
if is_yaml:
|
|
252
|
+
b = path.read_bytes()
|
|
253
|
+
obj = cls.parse_raw(
|
|
254
|
+
b,
|
|
255
|
+
content_type=content_type,
|
|
256
|
+
encoding=encoding,
|
|
257
|
+
proto=proto,
|
|
258
|
+
allow_pickle=allow_pickle,
|
|
259
|
+
)
|
|
260
|
+
else:
|
|
261
|
+
obj = load_file(
|
|
262
|
+
path,
|
|
263
|
+
proto=proto,
|
|
264
|
+
content_type=content_type,
|
|
265
|
+
encoding=encoding,
|
|
266
|
+
allow_pickle=allow_pickle,
|
|
267
|
+
json_loads=cls.__config__.json_loads,
|
|
268
|
+
)
|
|
269
|
+
return obj
|
|
270
|
+
|
|
271
|
+
@classmethod
|
|
272
|
+
def __try_update_forward_refs__(cls, **localns: Any) -> None:
|
|
273
|
+
"""
|
|
274
|
+
Same as update_forward_refs but will not raise exception
|
|
275
|
+
when forward references are not defined.
|
|
276
|
+
"""
|
|
277
|
+
try:
|
|
278
|
+
if issubclass(cls, BaseModel):
|
|
279
|
+
super().__try_update_forward_refs__(**localns) # type: ignore
|
|
280
|
+
except AttributeError:
|
|
281
|
+
pass
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from pydantic.v1 import BaseModel
|
|
2
|
+
|
|
3
|
+
from .mixin import YamlModelMixin
|
|
4
|
+
|
|
5
|
+
_pre_doc = """`pydantic.BaseModel` class with built-in YAML support.
|
|
6
|
+
|
|
7
|
+
You can alternatively inherit from this to implement your model:
|
|
8
|
+
`(pydantic_yaml.YamlModelMixin, pydantic.BaseModel)`
|
|
9
|
+
|
|
10
|
+
See Also
|
|
11
|
+
--------
|
|
12
|
+
pydantic-yaml: https://github.com/NowanIlfideme/pydantic-yaml
|
|
13
|
+
pydantic: https://pydantic-docs.helpmanual.io/
|
|
14
|
+
pyyaml: https://pyyaml.org/
|
|
15
|
+
ruamel.yaml: https://yaml.readthedocs.io/en/latest/index.html
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class YamlModel(YamlModelMixin, BaseModel):
|
|
20
|
+
__doc__ = _pre_doc + BaseModel.__doc__
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Marker file for PEP 561. This package uses inline types.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.9.0"
|