python-dictattr 0.0.2__tar.gz → 0.0.4__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.2
3
+ Version: 0.0.4
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
@@ -4,10 +4,10 @@
4
4
  from __future__ import annotations
5
5
 
6
6
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
7
- __version__ = (0, 0, 2)
7
+ __version__ = (0, 0, 4)
8
8
  __all__ = [
9
- "odict", "AttrDict", "MapAttr", "MuMapAttr",
10
- "DictAttr", "ChainDictAttr", "UserDictAttr",
9
+ "odict", "AttrDict", "MapAttr", "MuMapAttr", "DictAttr",
10
+ "ChainDictAttr", "UserDictAttr", "PriorityUserDictAttr",
11
11
  ]
12
12
 
13
13
  from collections import UserDict
@@ -25,6 +25,12 @@ class odict(dict[K, V]):
25
25
  __setattr__ = dict.__setitem__ # type: ignore
26
26
  __delattr__ = dict.__delitem__ # type: ignore
27
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
+
28
34
 
29
35
  class AttrDict(dict[K, V]):
30
36
 
@@ -32,14 +38,19 @@ class AttrDict(dict[K, V]):
32
38
  super().__init__(*args, **kwds)
33
39
  self.__dict__ = self # type: ignore
34
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
+
35
47
 
36
48
  @Mapping.register
37
49
  class MapAttr(Generic[K, V]):
38
50
 
39
- def __init__(self, d: None | dict = None, /):
51
+ def __init__(self, /, *args, **kwds):
40
52
  self.__dict__: dict[K, V] # type: ignore
41
- if d is not None:
42
- self.__dict__ = d
53
+ self.__dict__.update(*args, **kwds)
43
54
 
44
55
  def __contains__(self, key, /) -> bool:
45
56
  return key in self.__dict__
@@ -61,8 +72,16 @@ class MapAttr(Generic[K, V]):
61
72
  return f"{mod}.{cls.__qualname__}({self.__dict__})"
62
73
 
63
74
  @classmethod
64
- def of(cls, /, *args, **kwds) -> Self:
65
- return cls(dict(*args, **kwds))
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
66
85
 
67
86
 
68
87
  @MutableMapping.register
@@ -105,25 +124,41 @@ class ChainDictAttr(DictAttr[K, V | "ChainDictAttr"]):
105
124
  return d
106
125
 
107
126
 
108
- class UserDictAttr(UserDict[K, V]):
127
+ class UserDictAttr(UserDict):
128
+
129
+ def __getattr__(self, attr, /):
130
+ try:
131
+ return self[attr]
132
+ except KeyError as e:
133
+ raise AttributeError(attr) from e
134
+
135
+ def __getitem__(self, key, /):
136
+ d = super().__getitem__(key)
137
+ if isinstance(d, Mapping) and not isinstance(d, __class__): # type: ignore
138
+ return type(self)(d)
139
+ return d
140
+
141
+ def __repr__(self, /) -> str:
142
+ cls = type(self)
143
+ name = cls.__qualname__
144
+ if (module := cls.__module__) != "__main__":
145
+ name = f"{module}.{name}"
146
+ return f"{name}.of({self.data!r})"
109
147
 
110
148
  @classmethod
111
149
  def of(cls, m: Mapping, /) -> Self:
112
150
  self = cls()
113
- self.__dict__["data"] = m # type: ignore
151
+ self.__dict__["data"] = m
114
152
  return self
115
153
 
154
+
155
+ class PriorityUserDictAttr(UserDictAttr):
156
+
116
157
  def __delattr__(self, attr, /):
117
158
  try:
118
159
  del self[attr]
119
160
  except KeyError:
120
- try:
121
- super().__delattr__(attr)
122
- except KeyError:
123
- raise AttributeError(attr)
124
-
125
- def __getattr__(self, attr, /):
126
- return getattr(self.data, attr)
161
+ super().__delattr__(attr)
127
162
 
128
163
  def __getattribute__(self, attr, /):
129
164
  if attr in ("__dict__", "data") or attr == f"__{attr.strip('_')}__":
@@ -133,11 +168,8 @@ class UserDictAttr(UserDict[K, V]):
133
168
  except KeyError:
134
169
  return super().__getattribute__(attr)
135
170
 
136
- def __getitem__(self, key, /) -> V | Self: # type: ignore
137
- d = super().__getitem__(key)
138
- if type(d) is dict:
139
- return type(self)(d)
140
- return d
171
+ def __getattr__(self, attr, /):
172
+ raise AttributeError(attr)
141
173
 
142
174
  def __setattr__(self, attr, val, /):
143
175
  if attr == "data" and "data" not in self.__dict__:
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-dictattr"
3
- version = "0.0.2"
3
+ version = "0.0.4"
4
4
  description = "Python dictattr."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"
File without changes