Browse Source

Added Checked_data_value for datahandlers

m.orban 7 years ago
parent
commit
56b3b9d7ab
2 changed files with 71 additions and 87 deletions
  1. 57
    61
      lodel/leapi/datahandlers/base_classes.py
  2. 14
    26
      lodel/leapi/datahandlers/references.py

+ 57
- 61
lodel/leapi/datahandlers/base_classes.py View File

@@ -8,9 +8,11 @@ import copy
8 8
 import importlib
9 9
 import inspect
10 10
 import warnings
11
-
11
+from lodel.exceptions import *
12 12
 from lodel import logger
13 13
 
14
+class DataNoneValid(Exception):
15
+    pass
14 16
 
15 17
 class FieldValidationError(Exception):
16 18
     pass
@@ -31,6 +33,7 @@ class DataHandler(object):
31 33
     ##@brief List fields that will be exposed to the construct_data_method
32 34
     _construct_datas_deps = []
33 35
     
36
+    directly_editable = True
34 37
     ##@brief constructor
35 38
     # @param internal False | str : define whether or not a field is internal
36 39
     # @param immutable bool : indicates if the fieldtype has to be defined in child classes of LeObject or if it is
@@ -53,7 +56,6 @@ class DataHandler(object):
53 56
             if error:
54 57
                 raise error
55 58
             del(kwargs['default'])
56
-
57 59
         for argname, argval in kwargs.items():
58 60
             setattr(self, argname, argval)
59 61
 
@@ -74,23 +76,32 @@ class DataHandler(object):
74 76
     def is_internal(self):
75 77
         return self.internal is not False
76 78
 
77
-    ##@brief calls the data_field defined _check_data_value() method
78
-    #@ingroup lodel2_dh_checks
79
-    #@warning DO NOT REIMPLEMENT THIS METHOD IN A CUSTOM DATAHANDLER (see
80
-    #@ref _construct_data() and @ref lodel2_dh_check_impl )
81
-    #@return tuple (value, error|None)
82
-    def check_data_value(self, value):
79
+
80
+    def _check_data_value(self, value):
83 81
         if value is None:
84 82
             if not self.nullable:
85
-                return None, TypeError("'None' value but field is not nullable")
86
-            return None, None
87
-        return self._check_data_value(value)
88
-    
89
-    ##@brief Designed to be implemented in child classes
90
-    def _check_data_value(self, value):
91
-        
83
+                print(LodelExeption)
84
+                raise LodelExceptions("None value is forbidden")
85
+            print(self.nullable, value)
86
+            raise DataNoneValid("None with a nullable. GOTO CHECK")
87
+        return value, None
88
+
89
+#
90
+#    ##@brief calls the data_field defined _check_data_value() method
91
+#    #@ingroup lodel2_dh_checks
92
+#    #@warning DO NOT REIMPLEMENT THIS METHOD IN A CUSTOM DATAHANDLER (see
93
+#    #@ref _construct_data() and @ref lodel2_dh_check_impl )
94
+#    #@return tuple (value, error|None)
95
+    def check_data_value(self, value):
96
+        try:
97
+            self._check_data_value(value)
98
+        except DataNoneValid as expt:
99
+            return value, None
100
+        except LodelExceptions as expt:
101
+            return None, expt
92 102
         return value, None
93 103
 
104
+#
94 105
     ##@brief checks if this class can override the given data handler
95 106
     # @param data_handler DataHandler
96 107
     # @return bool
@@ -250,11 +261,15 @@ class Reference(DataHandler):
250 261
     # @param internal bool : if False, the field is not internal
251 262
     # @param **kwargs : other arguments
252 263
     def __init__(self, allowed_classes = None, back_reference = None, internal=False, **kwargs):
253
-        ##@brief set of allowed LeObject child classes
254 264
         self.__allowed_classes = set() if allowed_classes is None else set(allowed_classes)
255
-        ##@brief Stores back references informations
256
-        self.__back_reference = None
257
-        self.__set_back_reference(back_reference)
265
+        self.allowed_classes = list() if allowed_classes is None else allowed_classes
266
+        
267
+        if back_reference is not None:
268
+            if len(back_reference) != 2:
269
+                raise ValueError("A tuple (classname, fieldname) expected but got '%s'" % back_reference)
270
+            #if not issubclass(lodel.leapi.leobject.LeObject, back_reference[0]) or not isinstance(back_reference[1], str):
271
+            #    raise TypeError("Back reference was expected to be a tuple(<class LeObject>, str) but got : (%s, %s)" % (back_reference[0], back_reference[1]))
272
+        self.__back_reference = back_reference
258 273
         super().__init__(internal=internal, **kwargs)
259 274
  
260 275
     ##@brief Property that takes value of a copy of the back_reference tuple
@@ -275,30 +290,22 @@ class Reference(DataHandler):
275 290
         return copy.copy(self.__allowed_classes)
276 291
 
277 292
     ##@brief Set the back reference for this field.
278
-    def __set_back_reference(self, back_reference):
279
-        if back_reference is None:
280
-            return
281
-        if len(back_reference) != 2:
282
-            raise LodelDataHandlerException("A tuple(LeObjectChild, fieldname) \
283
-expected but got '%s'" % back_reference)
284
-        
293
+    def _set_back_reference(self, back_reference):
285 294
         self.__back_reference = back_reference
286 295
 
287 296
     ##@brief Check value
288 297
     #@param value *
289 298
     #@return tuple(value, exception)
290 299
     #@todo implement the check when we have LeObject to check value
291
-    def check_data_value(self, value):
292
-        for elt in self.__allowed_classes:
293
-            for k, v in elt.fields().items():
294
-            # k is a fieldname and v is a datahandler instance
295
-                if v.check_data_value(value)[0] is not None:
296
-                    return value, None
297
-
298
-    def construct_data(self, emcomponent, fname, datas, cur_value)
299
-        super().construct_data(self, emcomponent, fname, datas, cur_value)
300
-
300
+    def _check_data_value(self, value):
301
+        super()._check_data_value(value)
302
+        elt = self.__allowed_classes[0]
303
+        uid = elt.uid_fieldname()[0]# TODO multiple uid is broken
304
+        if (expt is None and not (isinstance(value, LeObject)) or (value is uid)):
305
+            raise FieldValidationError("LeObject instance or id exxpected for a reference field")
301 306
 
307
+    def construct_data(self, emcomponent, fname, datas, cur_value):
308
+        super().construct_data(emcomponent, fname, datas, cur_value)
302 309
 
303 310
     ##@brief Check datas consistency
304 311
     #@param emcomponent EmComponent : An EmComponent child class instance
@@ -315,8 +322,7 @@ expected but got '%s'" % back_reference)
315 322
             return rep
316 323
         if self.back_reference is None:
317 324
             return True
318
-        #Checking back reference consistency
319
-
325
+        
320 326
         # !! Reimplement instance fetching in construct data !!
321 327
         dh = emcomponent.field(fname)
322 328
         uid = datas[emcomponent.uid_fieldname()[0]] #multi uid broken here
@@ -341,12 +347,11 @@ class SingleRef(Reference):
341 347
     def __init__(self, allowed_classes = None, **kwargs):
342 348
         super().__init__(allowed_classes = allowed_classes)
343 349
  
344
-    def _check_data_value(self, value):
345
-        val, expt = super()._check_data_value(value)
346
-        if not isinstance(expt, Exception):
347
-            if len(val) > 1:
348
-                return None, FieldValidationError("Only single values are allowed for SingleRef fields")
349
-        return val, expt
350
+    def check_data_value(self, value):
351
+        super()._check_data_value(value)
352
+        if (expt is None and (len(val)>1)):
353
+            raise FieldValidationError("List or string expected for a set field")
354
+
350 355
 
351 356
 
352 357
 ##@brief This class represent a data_handler for multiple references to another object
@@ -363,25 +368,16 @@ class MultipleRef(Reference):
363 368
         super().__init__(**kwargs)
364 369
 
365 370
         
366
-    def check_data_value(self, value):
367
-        value, expt = super().check_data_value(value)
368
-        if expt is not None:
369
-            #error in parent
370
-            return value, expt
371
-        elif value is None:
372
-            #none value
373
-            return value, expt
374
-
375
-        expt = None
376
-     
377
-        if isinstance(value, str):
378
-            value, expt = super()._check_data_value(value)
379
-        elif not hasattr(value, '__iter__'):
380
-            return None, FieldValidationError("MultipleRef has to be an iterable or a string, '%s' found" % value)
371
+    def _check_data_value(self, value):
372
+        super()._check_data_value(value)
373
+        if not hasattr(value, '__iter__'):
374
+            raise FieldValidationError("MultipleRef has to be an iterable or a string, '%s' found" % value)
381 375
         if self.max_item is not None:
382 376
             if self.max_item < len(value):
383
-                return None, FieldValidationError("Too many items")
384
-        return value, expt
377
+                raise FieldValidationError("Too many items")
378
+        ref_list = []
379
+        for v in value.items():
380
+            ref_list.append(super()._check_data_value(v))
385 381
 
386 382
     def construct_data(self, emcomponent, fname, datas, cur_value):
387 383
         cur_value = super().construct_data(emcomponent, fname, datas, cur_value)

+ 14
- 26
lodel/leapi/datahandlers/references.py View File

@@ -1,5 +1,5 @@
1 1
 # -*- coding: utf-8 -*-
2
-from lodel.leapi.datahandlers.base_classes import Reference, MultipleRef, SingleRef, FieldValidationError
2
+from lodel.leapi.datahandlers.base_classes import Reference, MultipleRef, SingleRef, FieldValidationError, DataNoneValid
3 3
 
4 4
 from lodel import logger
5 5
 
@@ -21,14 +21,9 @@ class List(MultipleRef):
21 21
     # @param value *
22 22
     # @return tuple(value, exception)
23 23
     def _check_data_value(self, value):
24
-        if isinstance(value, list) or isinstance(value, str):
25
-            val, expt = super()._check_data_value(value)
26
-        else:
27
-            return None, FieldValidationError("List or string expected for a list field")
28
-        #if not isinstance(expt, Exception):
29
-        #    val = list(val)
30
-
31
-        return val, expt
24
+        super()._check_data_value(value)
25
+        if (expt is None and not (isinstance(val, list) or isinstance(val, str))):
26
+            raise FieldValidationError("List or string expected for a set field")
32 27
 
33 28
 ##@brief Child class of MultipleRef where references are represented in the form of a python set
34 29
 class Set(MultipleRef):
@@ -44,11 +39,9 @@ class Set(MultipleRef):
44 39
     # @param value *
45 40
     # @return tuple(value, exception)
46 41
     def _check_data_value(self, value):
47
-        if isinstance(value, set) or isinstance(value, str):
48
-            val, expt = super()._check_data_value(value)
49
-        else:
50
-            return None, FieldValidationError("Set or string expected for a set field")
51
-        return val, expt
42
+        super()._check_data_value(value)
43
+        if (expt is None and not (isinstance(val, set) or isinstance(val, str))):
44
+            raise FieldValidationError("Set or string expected for a set field")
52 45
     
53 46
 ##@brief Child class of MultipleRef where references are represented in the form of a python dict
54 47
 class Map(MultipleRef):
@@ -64,16 +57,14 @@ class Map(MultipleRef):
64 57
     # @param value *
65 58
     # @return tuple(value, exception)
66 59
     def _check_data_value(self, value):
67
-        val, expt = super()._check_data_value(value)
68
-        if not isinstance(value, dict):
69
-            return None, FieldValidationError("Values for dict fields should be dict")
70
-        return (
71
-                None if isinstance(expt, Exception) else value,
72
-                expt)
60
+        super()._check_data_value(value)
61
+        if (expt is None and not isinstance(val, dict)):
62
+            raise FieldValidationError("Values for dict fields should be dict")
73 63
 
74 64
 ##@brief This Reference class is designed to handler hierarchy with some constraint
75 65
 class Hierarch(MultipleRef):
76 66
     
67
+    directly_editable = False
77 68
     ##@brief Instanciate a data handler handling hierarchical relation with constraints
78 69
     # @param back_reference tuple : Here it is mandatory to have a back ref (like a parent field)
79 70
     # @param max_depth int | None :  limit of depth
@@ -85,9 +76,6 @@ class Hierarch(MultipleRef):
85 76
                             **kwargs)
86 77
 
87 78
     def _check_data_value(self, value):
88
-        if isinstance(value, list) or isinstance(value, str):
89
-            val, expt = super()._check_data_value(value)
90
-        else:
91
-            return None, FieldValidationError("Set or string expected for a set field")
92
-        return val, expt
93
-
79
+        super()._check_data_value(value)
80
+        if (expt is None and not (isinstance(val, list) or isinstance(val, str))):
81
+            raise FieldValidationError("List or string expected for a set field")

Loading…
Cancel
Save