1
- from .validations import registered_functions
1
+ from .validations import types
2
2
from .transformations import registered_transformation
3
3
from .exceptions import Invalid
4
4
5
5
NESTED = "nested"
6
- TYPELIST = "list"
7
- VALIDATOR = "type"
8
6
OPTIONAL = "optional"
9
- NULLABLE = "null_able"
10
- TYPEASOARR = "aso_array"
11
- SKIPFAILED = "skip_failed"
12
- TYPELISTDICTS = "list_dicts"
7
+ NULLABLE = "nullable"
13
8
DEFAULT = "default"
14
9
EMPTYLIST = "empty_list"
15
10
TRANSFORM = "transform"
16
11
PRETRANSFORM = "pre_transform"
12
+ SKIPFAILED = "skip_failed"
17
13
18
- special_arguments = {VALIDATOR , NESTED , TYPELIST , TYPEASOARR , SKIPFAILED , NULLABLE , OPTIONAL , DEFAULT , PRETRANSFORM ,
19
- TRANSFORM , TYPELISTDICTS , EMPTYLIST }
20
-
21
-
22
- def get_validation_func (item ):
23
- try :
24
- return registered_functions [item [VALIDATOR ]]
25
- except KeyError :
26
- raise Invalid (f"{ item .get (VALIDATOR )} is not registered as type" )
27
-
14
+ TYPE = "type"
15
+ TYPELIST = "list"
16
+ TYPEDICT = "dict"
17
+ TYPEASOARR = "aso_array"
18
+ TYPELISTDICTS = "list_dicts"
28
19
29
- def get_validation_args ( item ):
30
- return { k : v for k , v , in item . items () if k not in special_arguments }
20
+ special_arguments = { NESTED , TYPELIST , TYPEASOARR , SKIPFAILED , NULLABLE , OPTIONAL , DEFAULT , PRETRANSFORM ,
21
+ TRANSFORM , TYPELISTDICTS , EMPTYLIST , TYPEDICT , TYPE }
31
22
32
23
33
24
def get_transformation_func (item , type_transformation ):
@@ -64,7 +55,6 @@ def scale(input_dict, counter_dict):
64
55
65
56
validated_items = {}
66
57
for key , item in counter_dict .items ():
67
-
68
58
try :
69
59
val = input_dict [key ]
70
60
except KeyError :
@@ -76,40 +66,47 @@ def scale(input_dict, counter_dict):
76
66
else :
77
67
raise Invalid (f'key:"{ key } " is not set' )
78
68
79
- # # if the value is None, check for default value or check if it was required
69
+ # if the value is None check if value is allowed to be None
80
70
if val is None and item .get (NULLABLE ):
81
71
validated_items [key ] = None
82
72
continue
83
73
84
74
try :
85
- validation_func = registered_functions [item [VALIDATOR ]]
75
+ validation_func = types [item [TYPE ]]
86
76
except KeyError :
87
- raise Invalid (f"{ item .get (VALIDATOR )} is not registered as type" )
88
-
89
- validation_args = {k : v for k , v , in item .items () if k not in special_arguments }
77
+ raise Invalid (f"{ item .get (TYPE )} is not registered as type" )
90
78
91
79
pre_transformation = get_transformation_func (item , PRETRANSFORM )
92
80
post_transformation = get_transformation_func (item , TRANSFORM )
93
81
94
82
# the validation can be done on top level, life is good
95
83
if NESTED not in item :
96
- validated_items [key ] = post_transformation (validation_func (key = key , val = pre_transformation (val ), ** validation_args ))
84
+ validated_items [key ] = post_transformation (validation_func (key = key , val = pre_transformation (val ), ** item ))
85
+ continue
86
+
87
+ type_ = item ["type" ]
88
+ if type_ == TYPEDICT :
89
+ validation_func (key = key , val = val , ** item )
90
+ validated_items [key ] = post_transformation (scale (pre_transformation (input_dict [key ]), counter_dict [key ][NESTED ]))
97
91
98
- elif TYPELIST in item :
92
+ elif type_ == TYPELIST :
93
+ validation_func (key = key , val = val , ** item )
99
94
validated_items [key ] = item .get (EMPTYLIST , []) if len (val ) == 0 else []
100
95
96
+ try :
97
+ validation_func = types [item [NESTED ][TYPE ]]
98
+ except KeyError :
99
+ raise Invalid (f"{ item [NESTED ].get (TYPE )} is not registered as type" )
100
+
101
101
for nested_item in val :
102
- # within a list a item should be skipable
103
102
try :
104
- validated_items [key ].append (post_transformation (validation_func (key = key , val = pre_transformation (nested_item ), ** validation_args )))
103
+ validated_items [key ].append (post_transformation (validation_func (key = key , val = pre_transformation (nested_item ), ** item [ NESTED ] )))
105
104
except Invalid :
106
105
if not item .get (SKIPFAILED ):
107
106
raise
108
107
109
- # the item is nested with a list of dictionary items
110
- elif TYPELISTDICTS in item :
111
-
112
- validation_func (key = key , val = val , ** validation_args )
108
+ elif type_ == TYPELISTDICTS :
109
+ validation_func (key = key , val = val , ** item )
113
110
validated_items [key ] = []
114
111
for nested_item in val :
115
112
try :
@@ -118,22 +115,20 @@ def scale(input_dict, counter_dict):
118
115
if not item .get (SKIPFAILED ):
119
116
raise
120
117
121
- # the item is nested. we have to start over to do the same the one level deeper
122
- elif not item .get (TYPEASOARR , False ):
123
- validated_items [key ] = post_transformation (scale (pre_transformation (input_dict [key ]), counter_dict [key ][NESTED ]))
124
-
125
- # the item is a "associative array" dictionary e.g keys are numerical indexes
126
- else :
127
- validation_func (key = key , val = val , ** validation_args )
118
+ elif type_ == TYPEASOARR :
119
+ validation_func (key = key , val = val , ** item )
128
120
129
121
for nested_key , nested_val in val .items ():
130
- # make sure dictionary is present.
122
+ # TODO this could be nicer
131
123
if key not in validated_items :
132
124
validated_items [key ] = {}
133
125
if nested_key not in validated_items [key ]:
134
126
validated_items [key ][nested_key ] = {}
135
127
136
- validated_items [key ][nested_key ] = scale (nested_val , counter_dict [key ][NESTED ])
128
+ validated_items [key ][nested_key ] = validate (nested_val , counter_dict [key ][NESTED ])
129
+
130
+ else :
131
+ raise Invalid (f"type { type_ } can't handle nested structures, use { TYPEASOARR } , { TYPELISTDICTS } , { TYPEDICT } instead" )
137
132
138
133
return validated_items
139
134
@@ -156,37 +151,44 @@ def validate(input_dict, counter_dict):
156
151
else :
157
152
raise Invalid (f'key:"{ key } " is not set' )
158
153
159
- # # if the value is None, check for default value or check if it was required
154
+ # if the value is None check if value is allowed to be None
160
155
if val is None and item .get (NULLABLE ):
161
156
validated_items [key ] = None
162
157
continue
163
158
164
159
try :
165
- validation_func = registered_functions [item [VALIDATOR ]]
160
+ validation_func = types [item [TYPE ]]
166
161
except KeyError :
167
- raise Invalid (f"{ item .get (VALIDATOR )} is not registered as type" )
168
-
169
- validation_args = {k : v for k , v , in item .items () if k not in special_arguments }
162
+ raise Invalid (f"{ item .get (TYPE )} is not registered as type" )
170
163
171
164
# the validation can be done on top level, life is good
172
165
if NESTED not in item :
173
- validated_items [key ] = validation_func (key = key , val = val , ** validation_args )
166
+ validated_items [key ] = validation_func (key = key , val = val , ** item )
167
+ continue
174
168
175
- elif TYPELIST in item :
169
+ type_ = item ["type" ]
170
+ if type_ == TYPEDICT :
171
+ validation_func (key = key , val = val , ** item )
172
+ validated_items [key ] = validate (input_dict [key ], counter_dict [key ][NESTED ])
173
+
174
+ elif type_ == TYPELIST :
175
+ validation_func (key = key , val = val , ** item )
176
176
validated_items [key ] = item .get (EMPTYLIST , []) if len (val ) == 0 else []
177
177
178
+ try :
179
+ validation_func = types [item [NESTED ][TYPE ]]
180
+ except KeyError :
181
+ raise Invalid (f"{ item [NESTED ].get (TYPE )} is not registered as type" )
182
+
178
183
for nested_item in val :
179
- # within a list a item should be skipable
180
184
try :
181
- validated_items [key ].append (validation_func (key = key , val = nested_item , ** validation_args ))
185
+ validated_items [key ].append (validation_func (key = key , val = nested_item , ** item [ NESTED ])) # ADD test item nested
182
186
except Invalid :
183
187
if not item .get (SKIPFAILED ):
184
188
raise
185
189
186
- # the item is nested with a list of dictionary items
187
- elif TYPELISTDICTS in item :
188
-
189
- validation_func (key = key , val = val , ** validation_args )
190
+ elif type_ == TYPELISTDICTS :
191
+ validation_func (key = key , val = val , ** item )
190
192
validated_items [key ] = []
191
193
for nested_item in val :
192
194
try :
@@ -195,21 +197,19 @@ def validate(input_dict, counter_dict):
195
197
if not item .get (SKIPFAILED ):
196
198
raise
197
199
198
- # the item is nested. we have to start over to do the same the one level deeper
199
- elif not item .get (TYPEASOARR , False ):
200
- validated_items [key ] = validate (input_dict [key ], counter_dict [key ][NESTED ])
201
-
202
- # the item is a "associative array" dictionary e.g keys are numerical indexes
203
- else :
204
- validation_func (key = key , val = val , ** validation_args )
200
+ elif type_ == TYPEASOARR :
201
+ validation_func (key = key , val = val , ** item )
205
202
206
203
for nested_key , nested_val in val .items ():
207
- # make sure dictionary is present.
204
+ # TODO this could be nicer
208
205
if key not in validated_items :
209
206
validated_items [key ] = {}
210
207
if nested_key not in validated_items [key ]:
211
208
validated_items [key ][nested_key ] = {}
212
209
213
210
validated_items [key ][nested_key ] = validate (nested_val , counter_dict [key ][NESTED ])
214
211
212
+ else :
213
+ raise Invalid (f"type { type_ } can't handle nested structures, use { TYPEASOARR } , { TYPELISTDICTS } , { TYPEDICT } instead" )
214
+
215
215
return validated_items
0 commit comments