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.
- {python_dictattr-0.0.1 → python_dictattr-0.0.3}/PKG-INFO +1 -1
- python_dictattr-0.0.3/dictattr/__init__.py +166 -0
- {python_dictattr-0.0.1 → python_dictattr-0.0.3}/pyproject.toml +1 -1
- python_dictattr-0.0.1/dictattr/.DS_Store +0 -0
- python_dictattr-0.0.1/dictattr/__init__.py +0 -103
- {python_dictattr-0.0.1 → python_dictattr-0.0.3}/LICENSE +0 -0
- {python_dictattr-0.0.1 → python_dictattr-0.0.3}/dictattr/py.typed +0 -0
- {python_dictattr-0.0.1 → python_dictattr-0.0.3}/readme.md +0 -0
|
@@ -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
|
+
|
|
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
|
|
File without changes
|
|
File without changes
|