Browse Source

Modification in backreference handling.

Now a backreference is represented by a tuple(LeObject child class, fieldname)
Yann Weber 8 years ago
parent
commit
2c47c71116
5 changed files with 23 additions and 36 deletions
  1. 7
    5
      Makefile
  2. BIN
      examples/em_test.pickle
  3. 4
    2
      lodel/leapi/datahandlers/base_classes.py
  4. 12
    12
      lodel/leapi/lefactory.py
  5. 0
    17
      lodel/leapi/leobject.py

+ 7
- 5
Makefile View File

1
 dyncode_filename='lodel/leapi/dyncode.py'
1
 dyncode_filename='lodel/leapi/dyncode.py'
2
 
2
 
3
-all: doc refresh_dyn
3
+all: test doc refresh_dyn
4
 
4
 
5
 doc: cleandoc
5
 doc: cleandoc
6
 	doxygen
6
 	doxygen
9
 em_test:
9
 em_test:
10
 	python3 em_test.py
10
 	python3 em_test.py
11
 
11
 
12
-refresh_dyn: clean_dyn em_test
13
-	python3 scripts/refreshdyn.py examples/em_test.pickle $(dyncode_filename)
14
-	
12
+dyncode: clean_dyn em_test
13
+	python3 scripts/refreshdyn.py examples/em_test.pickle $(dyncode_filename) && echo -e "\n\nCode generated in $(dyncode_filename)"
14
+
15
+tests:
16
+	./runtest -v
15
 
17
 
16
-.PHONY: clean clean_dyn cleandoc cleanpyc
18
+.PHONY: clean clean_dyn cleandoc cleanpyc tests
17
 
19
 
18
 clean: clean_dyn cleandoc cleanpyc
20
 clean: clean_dyn cleandoc cleanpyc
19
 
21
 

BIN
examples/em_test.pickle View File


+ 4
- 2
lodel/leapi/datahandlers/base_classes.py View File

183
 
183
 
184
     ## @brief Instanciation
184
     ## @brief Instanciation
185
     # @param allowed_classes list | None : list of allowed em classes if None no restriction
185
     # @param allowed_classes list | None : list of allowed em classes if None no restriction
186
-    # @param back_reference tuple | None : tuple containing (EmClass name, EmField name)
186
+    # @param back_reference tuple | None : tuple containing (LeObject child class, fieldname)
187
     # @param internal bool : if False, the field is not internal
187
     # @param internal bool : if False, the field is not internal
188
     # @param **kwargs : other arguments
188
     # @param **kwargs : other arguments
189
     def __init__(self, allowed_classes = None, back_reference = None, internal=False, **kwargs):
189
     def __init__(self, allowed_classes = None, back_reference = None, internal=False, **kwargs):
191
         if back_reference is not None:
191
         if back_reference is not None:
192
             if len(back_reference) != 2:
192
             if len(back_reference) != 2:
193
                 raise ValueError("A tuple (classname, fieldname) expected but got '%s'" % back_reference)
193
                 raise ValueError("A tuple (classname, fieldname) expected but got '%s'" % back_reference)
194
+            #if not issubclass(back_reference[0], LeObject) or not isinstance(back_reference[1], str):
195
+            #    raise TypeError("Back reference was expected to be a tuple(<class LeObject>, str) but got : (%s, %s)" % (back_reference[0], back_reference[1]))
194
         self.__back_reference = back_reference
196
         self.__back_reference = back_reference
195
         super().__init__(internal=internal, **kwargs)
197
         super().__init__(internal=internal, **kwargs)
196
     
198
     
197
     @property
199
     @property
198
     def back_reference(self):
200
     def back_reference(self):
199
-        return self.__back_reference
201
+        return copy.copy(self.__back_reference)
200
 
202
 
201
     ## @brief Set the back reference for this field.
203
     ## @brief Set the back reference for this field.
202
     def _set_back_reference(self, back_reference):
204
     def _set_back_reference(self, back_reference):

+ 12
- 12
lodel/leapi/lefactory.py View File

11
     
11
     
12
     # Generation of LeObject child classes code
12
     # Generation of LeObject child classes code
13
     cls_code, modules, bootstrap_instr = generate_classes(model)
13
     cls_code, modules, bootstrap_instr = generate_classes(model)
14
-    # Completing bootstrap with back_reference bootstraping
15
-    for leoname in [ LeObject.name2objname(emcls.uid) for emcls in get_classes(model) ]:
16
-        bootstrap_instr += """
17
-{leobject}._backref_init()
18
-""".format(leobject = leoname)
19
-    bootstrap_instr += """
20
-del(LeObject._set__fields)
21
-del(LeObject._backref_init)
22
-"""
23
 
14
 
24
     # Header
15
     # Header
25
     imports = """from lodel.leapi.leobject import LeObject
16
     imports = """from lodel.leapi.leobject import LeObject
59
     #dh_module_name = DataHandler.module_name(emfield.data_handler_name)+'.DataHandler'
50
     #dh_module_name = DataHandler.module_name(emfield.data_handler_name)+'.DataHandler'
60
     get_handler_class_instr = 'DataField.from_name(%s)' % repr(emfield.data_handler_name)
51
     get_handler_class_instr = 'DataField.from_name(%s)' % repr(emfield.data_handler_name)
61
     options = []
52
     options = []
53
+    for name, val in emfield.data_handler_options.items():
54
+        if name == 'back_reference' and isinstance(val, tuple):
55
+            options.append('{optname}: ({leo_name}, {fieldname})'.format(
56
+                optname = repr(name),
57
+                leo_name = LeObject.name2objname(val[0]),
58
+                fieldname = repr(val[1]),))
59
+        else:
60
+            options.append(repr(name)+': '+forge_optval(val))
62
 
61
 
63
-    return ('%s(**{' % get_handler_class_instr)+(', '.join([repr(name)+': '+forge_optval(val) for name, val in emfield.data_handler_options.items()])) + '})'
62
+    return '{handler_instr}(**{{ {options} }})'.format(
63
+                                                        handler_instr = get_handler_class_instr,
64
+                                                        options = ', '.join(options))
64
             
65
             
65
-
66
+## @brief Return a python repr of option values
66
 def forge_optval(optval):
67
 def forge_optval(optval):
67
     if isinstance(optval, dict):
68
     if isinstance(optval, dict):
68
         return '{' + (', '.join( [ '%s: %s' % (repr(name), forge_optval(val)) for name, val in optval.items()])) + '}'
69
         return '{' + (', '.join( [ '%s: %s' % (repr(name), forge_optval(val)) for name, val in optval.items()])) + '}'
119
         res += em_cls_code
120
         res += em_cls_code
120
         # Dyncode bootstrap instructions
121
         # Dyncode bootstrap instructions
121
         bootstrap += """{classname}._set__fields({fields})
122
         bootstrap += """{classname}._set__fields({fields})
122
-#del({classname}._set__fields)
123
 """.format(
123
 """.format(
124
     classname = LeObject.name2objname(em_class.uid),
124
     classname = LeObject.name2objname(em_class.uid),
125
     fields = '{' + (', '.join(['\n\t%s: %s' % (repr(emfield.uid),data_handler_constructor(emfield)) for emfield in em_class.fields()])) + '}',
125
     fields = '{' + (', '.join(['\n\t%s: %s' % (repr(emfield.uid),data_handler_constructor(emfield)) for emfield in em_class.fields()])) + '}',

+ 0
- 17
lodel/leapi/leobject.py View File

157
         except AttributeError:
157
         except AttributeError:
158
             raise NameError("No LeObject named '%s'" % leobject_name)
158
             raise NameError("No LeObject named '%s'" % leobject_name)
159
     
159
     
160
-    ## @brief Method designed to "bootstrap" fields by settings their back references
161
-    # 
162
-    # @note called once at dyncode load
163
-    # @note doesn't do any consistency checks, it assume that checks has been done EM side
164
-    # @warning after dyncode load this method is deleted
165
-    @classmethod
166
-    def _backref_init(cls):
167
-        for fname,field in cls._fields.items():
168
-            #if field.is_reference():
169
-            #    print(fname, field.back_reference)
170
-            if field.is_reference() and field.back_reference is not None:
171
-                cls_name, field_name = field.back_reference
172
-                bref_leobject = cls.name2class(cls.name2objname(cls_name))
173
-                if field_name not in bref_leobject._fields:
174
-                    raise NameError("LeObject %s doesn't have a field named '%s'" % (cls_name, field_name))
175
-                field._set_back_reference(bref_leobject._fields[field_name])
176
-
177
     @classmethod
160
     @classmethod
178
     def is_abstract(cls):
161
     def is_abstract(cls):
179
         return cls._abstract
162
         return cls._abstract

Loading…
Cancel
Save