python-datamodel 0.8.13__cp313-cp313-win_amd64.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.
@@ -0,0 +1,128 @@
1
+ import sys
2
+ from collections.abc import MutableMapping, Iterator, Iterable
3
+ from typing import Any, Optional, Union, Literal
4
+ from typing_extensions import TypedDict
5
+ from datamodel import Field
6
+
7
+ if sys.version_info < (3, 10):
8
+ from typing_extensions import ParamSpec
9
+ else:
10
+ from typing import ParamSpec
11
+ P = ParamSpec("P")
12
+
13
+
14
+ class ClassDictConfig(TypedDict, total=False):
15
+ """
16
+ Configuration dictionary for ClassDict-based classes.
17
+ `total=False` means all keys are optional.
18
+ """
19
+ extra: Literal['allow', 'ignore', 'forbid']
20
+ validate_assignment: bool
21
+ parse_values: bool
22
+
23
+
24
+ class ClassDict(dict, MutableMapping):
25
+ """ClassDict.
26
+
27
+ Mapping that works like both a simple Dictionary or a Mutable Object.
28
+ """
29
+ def __init__(self, *args: P.args, data: Optional[Union[tuple, dict]] = None, default: Any = None, **kwargs: P.kwargs):
30
+ self._columns: list = []
31
+ self.mapping = {}
32
+ self.default = default
33
+ self.mapping.update(*args, **kwargs)
34
+ self.update(data, **kwargs)
35
+
36
+ def update(self, items: Optional[Iterable] = None, **kwargs): # pylint: disable=W0221
37
+ if isinstance(items, dict):
38
+ for key, value in items.items():
39
+ # self.mapping[key] = value
40
+ self.mapping[key] = value
41
+ else:
42
+ for k,v in kwargs.items():
43
+ attr = getattr(self, k)
44
+ if isinstance(attr, Field):
45
+ try:
46
+ fn = attr.default
47
+ if callable(fn):
48
+ v = fn(v)
49
+ setattr(self, k, v)
50
+ else:
51
+ setattr(self, k, fn)
52
+ except KeyError:
53
+ pass
54
+ # self.mapping[k] = v
55
+ self.mapping[k] = v
56
+ self._columns = list(self.mapping.keys())
57
+
58
+ def __missing__(self, key):
59
+ return self.default
60
+
61
+ def items(self) -> zip: # type: ignore
62
+ return zip(self._columns, self.mapping)
63
+
64
+ def keys(self) -> list:
65
+ return self._columns
66
+
67
+ def set(self, key, value) -> None:
68
+ self.mapping[key] = value
69
+ if not key in self._columns:
70
+ self._columns.append(key)
71
+
72
+ ### Section: Simple magic methods
73
+ def __len__(self) -> int:
74
+ return len(self.mapping)
75
+
76
+ def __str__(self) -> str:
77
+ return f"<{type(self).__name__}({self.mapping})>"
78
+
79
+ def __repr__(self) -> str:
80
+ return f"<{type(self).__name__}({self.mapping})>"
81
+
82
+ def __contains__(self, key: str) -> bool:
83
+ return key in self._columns
84
+
85
+ def __delitem__(self, key) -> None:
86
+ value = self[key]
87
+ del self.mapping[key]
88
+ self._columns.remove(key)
89
+ self.pop(value, None)
90
+
91
+ def __delattr__(self, name: str) -> None:
92
+ value = self[name]
93
+ del self.mapping[name]
94
+ self._columns.remove(name)
95
+ self.pop(value, None)
96
+
97
+ def __setitem__(self, key, value):
98
+ self.mapping[key] = value
99
+ if not key in self._columns:
100
+ self._columns.append(key)
101
+
102
+ def __getitem__(self, key: Union[str, int]) -> Any:
103
+ """
104
+ Sequence-like operators
105
+ """
106
+ try:
107
+ return self.mapping[key]
108
+ except (KeyError, TypeError):
109
+ return None
110
+
111
+ def __getattr__(self, attr: str) -> Any:
112
+ """
113
+ Attributes for dict keys
114
+ """
115
+ try:
116
+ return self.__getitem__(attr)
117
+ except KeyError as ex:
118
+ raise KeyError(
119
+ f"User Error: invalid field name {attr} on {self.mapping!r}"
120
+ ) from ex
121
+ except TypeError as ex:
122
+ raise TypeError(
123
+ f"User Error: invalid attribute value on {self.mapping!r} for {attr}"
124
+ ) from ex
125
+
126
+ def __iter__(self) -> Iterator:
127
+ for value in self.mapping:
128
+ yield value