python-dictattr 0.0.1__tar.gz → 0.0.3__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-dictattr
3
- Version: 0.0.1
3
+ Version: 0.0.3
4
4
  Summary: Python dictattr.
5
5
  Home-page: https://github.com/ChenyangGao/web-mount-packs/tree/main/python-module/python-dictattr
6
6
  License: MIT
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env python3
2
+ # encoding: utf-8
3
+
4
+ from __future__ import annotations
5
+
6
+ __author__ = "ChenyangGao <https://chenyanggao.github.io>"
7
+ __version__ = (0, 0, 3)
8
+ __all__ = [
9
+ "odict", "AttrDict", "MapAttr", "MuMapAttr",
10
+ "DictAttr", "ChainDictAttr", "UserDictAttr",
11
+ ]
12
+
13
+ from collections import UserDict
14
+ from collections.abc import Iterator, Mapping, MutableMapping
15
+ from typing import Generic, Self, TypeVar
16
+
17
+
18
+ K = TypeVar("K")
19
+ V = TypeVar("V")
20
+
21
+
22
+ class odict(dict[K, V]):
23
+
24
+ __getattr__ = dict.__getitem__
25
+ __setattr__ = dict.__setitem__ # type: ignore
26
+ __delattr__ = dict.__delitem__ # type: ignore
27
+
28
+ def __hash__(self, /) -> int: # type: ignore
29
+ return id(self)
30
+
31
+ def __eq__(self, value, /) -> bool:
32
+ return self is value or super().__eq__(value)
33
+
34
+
35
+ class AttrDict(dict[K, V]):
36
+
37
+ def __init__(self, /, *args, **kwds):
38
+ super().__init__(*args, **kwds)
39
+ self.__dict__ = self # type: ignore
40
+
41
+ def __hash__(self, /) -> int: # type: ignore
42
+ return id(self)
43
+
44
+ def __eq__(self, value, /) -> bool:
45
+ return self is value or super().__eq__(value)
46
+
47
+
48
+ @Mapping.register
49
+ class MapAttr(Generic[K, V]):
50
+
51
+ def __init__(self, /, *args, **kwds):
52
+ self.__dict__: dict[K, V] # type: ignore
53
+ self.__dict__.update(*args, **kwds)
54
+
55
+ def __contains__(self, key, /) -> bool:
56
+ return key in self.__dict__
57
+
58
+ def __getitem__(self, key, /) -> V:
59
+ return self.__dict__[key]
60
+
61
+ def __iter__(self, /) -> Iterator[K]:
62
+ return iter(self.__dict__)
63
+
64
+ def __len__(self, /) -> int:
65
+ return len(self.__dict__)
66
+
67
+ def __repr__(self, /) -> str:
68
+ cls = type(self)
69
+ if (mod := cls.__module__) == "__main__":
70
+ return f"{cls.__qualname__}({self.__dict__})"
71
+ else:
72
+ return f"{mod}.{cls.__qualname__}({self.__dict__})"
73
+
74
+ @classmethod
75
+ def of(
76
+ cls,
77
+ d: None | dict[K, V] = None,
78
+ /,
79
+ ) -> Self:
80
+ if d is None:
81
+ return cls()
82
+ self = __class__.__new__(cls) # type: ignore
83
+ self.__dict__ = d
84
+ return self
85
+
86
+
87
+ @MutableMapping.register
88
+ class MuMapAttr(MapAttr[K, V]):
89
+
90
+ def __delitem__(self, key, /):
91
+ del self.__dict__[key]
92
+
93
+ def __setitem__(self, key: K, val: V, /):
94
+ self.__dict__[key] = val
95
+
96
+
97
+ class DictAttr(MuMapAttr[K, V]):
98
+
99
+ def __getattr__(self, attr, /):
100
+ return getattr(self.__dict__, attr)
101
+
102
+ def __getattribute__(self, attr, /):
103
+ if attr == "__dict__":
104
+ return super().__getattribute__(attr)
105
+ try:
106
+ return self[attr]
107
+ except KeyError:
108
+ return super().__getattribute__(attr)
109
+
110
+ def __getitem__(self, key, /) -> V | Self: # type: ignore
111
+ d = self.__dict__[key]
112
+ if type(d) is dict:
113
+ return type(self)(d)
114
+ return d
115
+
116
+
117
+ class ChainDictAttr(DictAttr[K, V | "ChainDictAttr"]):
118
+
119
+ def __getitem__(self, key, /) -> V | ChainDictAttr:
120
+ try:
121
+ return super().__getitem__(key)
122
+ except KeyError:
123
+ d = self.__dict__[key] = type(self)()
124
+ return d
125
+
126
+
127
+ class UserDictAttr(UserDict[K, V]):
128
+
129
+ @classmethod
130
+ def of(cls, m: Mapping, /) -> Self:
131
+ self = cls()
132
+ self.__dict__["data"] = m # type: ignore
133
+ return self
134
+
135
+ def __delattr__(self, attr, /):
136
+ try:
137
+ del self[attr]
138
+ except KeyError:
139
+ try:
140
+ super().__delattr__(attr)
141
+ except KeyError:
142
+ raise AttributeError(attr)
143
+
144
+ def __getattr__(self, attr, /):
145
+ return getattr(self.data, attr)
146
+
147
+ def __getattribute__(self, attr, /):
148
+ if attr in ("__dict__", "data") or attr == f"__{attr.strip('_')}__":
149
+ return super().__getattribute__(attr)
150
+ try:
151
+ return self[attr]
152
+ except KeyError:
153
+ return super().__getattribute__(attr)
154
+
155
+ def __getitem__(self, key, /) -> V | Self: # type: ignore
156
+ d = super().__getitem__(key)
157
+ if type(d) is dict:
158
+ return type(self)(d)
159
+ return d
160
+
161
+ def __setattr__(self, attr, val, /):
162
+ if attr == "data" and "data" not in self.__dict__:
163
+ self.__dict__["data"] = val
164
+ else:
165
+ self[attr] = val
166
+
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-dictattr"
3
- version = "0.0.1"
3
+ version = "0.0.3"
4
4
  description = "Python dictattr."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"
Binary file
@@ -1,103 +0,0 @@
1
- #!/usr/bin/env python3
2
- # encoding: utf-8
3
-
4
- __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 0, 1)
6
- __all__ = [
7
- "odict", "AttrDict", "MapAttr", "MuMapAttr", "DictAttr", "ChainDictAttr",
8
- ]
9
-
10
- from collections.abc import Iterator, Mapping, MutableMapping
11
- from typing import Generic, Self, TypeVar
12
-
13
-
14
- K = TypeVar("K")
15
- V = TypeVar("V")
16
-
17
-
18
- class odict(dict[K, V]):
19
-
20
- __getattr__ = dict.__getitem__
21
- __setattr__ = dict.__setitem__ # type: ignore
22
- __delattr__ = dict.__delitem__ # type: ignore
23
-
24
-
25
- class AttrDict(dict[K, V]):
26
-
27
- def __init__(self, /, *args, **kwds):
28
- super().__init__(*args, **kwds)
29
- self.__dict__ = self # type: ignore
30
-
31
-
32
- @Mapping.register
33
- class MapAttr(Generic[K, V]):
34
-
35
- def __init__(self, d: None | dict = None, /):
36
- self.__dict__: dict[K, V] # type: ignore
37
- if d is not None:
38
- self.__dict__ = d
39
-
40
- def __contains__(self, key, /) -> bool:
41
- return key in self.__dict__
42
-
43
- def __getitem__(self, key, /) -> V:
44
- return self.__dict__[key]
45
-
46
- def __iter__(self, /) -> Iterator[K]:
47
- return iter(self.__dict__)
48
-
49
- def __len__(self, /) -> int:
50
- return len(self.__dict__)
51
-
52
- def __repr__(self, /) -> str:
53
- cls = type(self)
54
- if (mod := cls.__module__) == "__main__":
55
- return f"{cls.__qualname__}({self.__dict__})"
56
- else:
57
- return f"{mod}.{cls.__qualname__}({self.__dict__})"
58
-
59
- @classmethod
60
- def of(cls, /, *args, **kwds) -> Self:
61
- return cls(dict(*args, **kwds))
62
-
63
-
64
- @MutableMapping.register
65
- class MuMapAttr(MapAttr[K, V]):
66
-
67
- def __delitem__(self, key, /):
68
- del self.__dict__[key]
69
-
70
- def __setitem__(self, key: K, val: V, /):
71
- self.__dict__[key] = val
72
-
73
-
74
- class DictAttr(MuMapAttr):
75
-
76
- def __getattr__(self, attr, /):
77
- return getattr(self.__dict__, attr)
78
-
79
- def __getattribute__(self, attr, /):
80
- if attr is "__dict__":
81
- return super().__getattribute__(attr)
82
- try:
83
- return self[attr]
84
- except KeyError:
85
- return super().__getattribute__(attr)
86
-
87
- def __getitem__(self, key, /):
88
- d = self.__dict__[key]
89
- if type(d) is dict:
90
- return type(self)(d)
91
- return d
92
-
93
-
94
- class ChainDictAttr(DictAttr):
95
-
96
- def __getitem__(self, key, /):
97
- try:
98
- super().__getitem__(key)
99
- except KeyError:
100
- d = type(self)()
101
- self.__dict__[key] = d.__dict__
102
- return d
103
-
File without changes