Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Commit 4a7a408

Browse files
committed
Refining dump/load implementation.
1 parent aa1987d commit 4a7a408

File tree

2 files changed

+166
-18
lines changed

2 files changed

+166
-18
lines changed

src/oidcmsg/impexp.py

+72-12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from typing import Any
12
from typing import List
23
from typing import Optional
34

@@ -9,12 +10,14 @@
910

1011
class ImpExp:
1112
parameter = {}
13+
special_load_dump = {}
14+
init_args = []
1215

1316
def __init__(self):
1417
pass
1518

1619
def dump_attr(self, cls, item, exclude_attributes: Optional[List[str]] = None) -> dict:
17-
if cls in [None, "", [], {}]:
20+
if cls in [None, 0, "", [], {}, bool]:
1821
val = item
1922
elif isinstance(item, Message):
2023
val = {qualified_name(item.__class__): item.to_dict()}
@@ -31,7 +34,7 @@ def dump(self, exclude_attributes: Optional[List[str]] = None) -> dict:
3134
_exclude_attributes = exclude_attributes or []
3235
info = {}
3336
for attr, cls in self.parameter.items():
34-
if attr in _exclude_attributes:
37+
if attr in _exclude_attributes or attr in self.special_load_dump:
3538
continue
3639

3740
item = getattr(self, attr, None)
@@ -40,33 +43,86 @@ def dump(self, exclude_attributes: Optional[List[str]] = None) -> dict:
4043

4144
info[attr] = self.dump_attr(cls, item, exclude_attributes)
4245

46+
for attr, d in self.special_load_dump.items():
47+
item = getattr(self, attr, None)
48+
if item:
49+
info[attr] = d["dump"](item, exclude_attributes=exclude_attributes)
50+
4351
return info
4452

45-
def _local_adjustments(self):
53+
def local_load_adjustments(self, **kwargs):
4654
pass
4755

48-
def load_attr(self, cls, item):
49-
if cls in [None, "", [], {}]:
56+
def load_attr(self,
57+
cls: Any,
58+
item: dict,
59+
init_args: Optional[dict] = None,
60+
load_args: Optional[dict] = None) -> Any:
61+
if load_args:
62+
_kwargs = {"load_args": load_args}
63+
_load_args = load_args
64+
else:
65+
_kwargs = {}
66+
_load_args = {}
67+
68+
if init_args:
69+
_kwargs["init_args"] = init_args
70+
71+
if cls in [None, 0, "", [], {}, bool]:
5072
val = item
5173
elif cls == object:
5274
val = importer(item)
5375
elif isinstance(cls, list):
54-
val = [cls[0]().load(v) for v in item]
76+
if isinstance(cls[0], str):
77+
_cls = importer(cls[0])
78+
else:
79+
_cls = cls[0]
80+
81+
if issubclass(_cls, ImpExp) and init_args:
82+
_args = {k: v for k, v in init_args.items() if k in _cls.init_args}
83+
else:
84+
_args = {}
85+
86+
val = [_cls(**_args).load(v, **_kwargs) for v in item]
5587
elif issubclass(cls, Message):
56-
val = cls().from_dict(item)
88+
_cls_name = list(item.keys())[0]
89+
_cls = importer(_cls_name)
90+
val = _cls().from_dict(item[_cls_name])
5791
else:
58-
val = cls().load(item)
92+
if issubclass(cls, ImpExp) and init_args:
93+
_args = {k: v for k, v in init_args.items() if k in cls.init_args}
94+
else:
95+
_args = {}
96+
97+
val = cls(**_args).load(item, **_kwargs)
5998

6099
return val
61100

62-
def load(self, item: dict):
101+
def load(self, item: dict,
102+
init_args: Optional[dict] = None,
103+
load_args: Optional[dict] = None):
104+
105+
if load_args:
106+
_kwargs = {"load_args": load_args}
107+
_load_args = load_args
108+
else:
109+
_kwargs = {}
110+
_load_args = {}
111+
112+
if init_args:
113+
_kwargs["init_args"] = init_args
114+
63115
for attr, cls in self.parameter.items():
64-
if attr not in item:
116+
if attr not in item or attr in self.special_load_dump:
65117
continue
66118

67-
setattr(self, attr, self.load_attr(cls, item[attr]))
119+
setattr(self, attr, self.load_attr(cls, item[attr], **_kwargs))
120+
121+
for attr, func in self.special_load_dump.items():
122+
if attr in item:
123+
setattr(self, attr, func["load"](item[attr], **_kwargs))
68124

69-
self._local_adjustments()
125+
self.local_load_adjustments(**_load_args)
70126
return self
71127

72128
def flush(self):
@@ -78,6 +134,10 @@ def flush(self):
78134
for attr, cls in self.parameter.items():
79135
if cls is None:
80136
setattr(self, attr, None)
137+
elif cls == 0:
138+
setattr(self, attr, 0)
139+
elif cls is bool:
140+
setattr(self, attr, False)
81141
elif cls == "":
82142
setattr(self, attr, "")
83143
elif cls == []:

src/oidcmsg/item.py

+94-6
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,66 @@
22
from typing import Optional
33

44
from oidcmsg.impexp import ImpExp
5+
from oidcmsg.message import Message
56
from oidcmsg.storage import importer
67
from oidcmsg.storage.utils import qualified_name
78

89

910
class DLDict(ImpExp):
1011
parameter = {
11-
"item_class": "",
1212
"db": {}
1313
}
1414

15-
def __init__(self):
15+
def __init__(self, **kwargs):
1616
ImpExp.__init__(self)
17-
self.db = {}
17+
self.db = kwargs
1818

1919
def __setitem__(self, key: str, val):
2020
self.db[key] = val
2121

2222
def __getitem__(self, key: str):
2323
return self.db[key]
2424

25+
def __delitem__(self, key:str):
26+
del self.db[key]
27+
2528
def dump(self, exclude_attributes: Optional[List[str]] = None) -> dict:
2629
res = {}
2730

28-
for k,v in self.db.items():
31+
for k, v in self.db.items():
2932
_class = qualified_name(v.__class__)
3033
res[k] = [_class, v.dump(exclude_attributes=exclude_attributes)]
3134

3235
return res
3336

34-
def load(self, spec: dict, **kwargs) -> "DLDict":
37+
def load(self, spec: dict,
38+
init_args: Optional[dict] = None,
39+
load_args: Optional[dict] = None
40+
) -> "DLDict":
41+
if load_args:
42+
_kwargs= {"load_args": load_args}
43+
_load_args = {}
44+
else:
45+
_load_args = {}
46+
_kwargs = {}
47+
48+
if init_args:
49+
_kwargs["init_args"] = init_args
50+
3551
for attr, (_item_cls, _item) in spec.items():
36-
self.db[attr] = importer(_item_cls)(**kwargs).load(_item)
52+
_cls = importer(_item_cls)
53+
54+
if issubclass(_cls, ImpExp) and init_args:
55+
_args = {k: v for k, v in init_args.items() if k in _cls.init_args}
56+
else:
57+
_args = {}
58+
59+
_x = _cls(**_args)
60+
_x.load(_item, **_kwargs)
61+
self.db[attr] = _x
62+
63+
self.local_load_adjustments(**_load_args)
64+
3765
return self
3866

3967
def keys(self):
@@ -47,3 +75,63 @@ def values(self):
4775

4876
def __contains__(self, item):
4977
return item in self.db
78+
79+
def get(self, item, default=None):
80+
return self.db.get(item, default)
81+
82+
def __len__(self):
83+
return len(self.db)
84+
85+
86+
def dump_dldict(item, exclude_attributes: Optional[List[str]] = None) -> dict:
87+
res = {}
88+
89+
for k, v in item.items():
90+
_class = qualified_name(v.__class__)
91+
if isinstance(v, Message):
92+
res[k] = [_class, v.to_dict()]
93+
else:
94+
res[k] = [_class, v.dump(exclude_attributes=exclude_attributes)]
95+
96+
return res
97+
98+
99+
def load_dldict(spec: dict,
100+
init_args: Optional[dict] = None,
101+
load_args: Optional[dict] = None
102+
) -> dict:
103+
db = {}
104+
105+
for attr, (_item_cls, _item) in spec.items():
106+
_class = importer(_item_cls)
107+
if issubclass(_class, Message):
108+
db[attr] = _class().from_dict(_item)
109+
else:
110+
if issubclass(_class, ImpExp) and init_args:
111+
_args = {k: v for k, v in init_args.items() if k in _class.init_args}
112+
else:
113+
_args = {}
114+
115+
db[attr] = _class(**_args).load(_item)
116+
117+
return db
118+
119+
120+
def dump_class_map(item, exclude_attributes: Optional[List[str]] = None) -> dict:
121+
_dump = {}
122+
for key, val in item.items():
123+
if isinstance(val, str):
124+
_dump[key] = val
125+
else:
126+
_dump[key] = qualified_name(val)
127+
return _dump
128+
129+
130+
def load_class_map(spec: dict,
131+
init_args: Optional[dict] = None,
132+
load_args: Optional[dict] = None
133+
) -> dict:
134+
_item = {}
135+
for key, val in spec.items():
136+
_item[key] = importer(val)
137+
return _item

0 commit comments

Comments
 (0)