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,6 +1,6 @@
1 1
 dyncode_filename='lodel/leapi/dyncode.py'
2 2
 
3
-all: doc refresh_dyn
3
+all: test doc refresh_dyn
4 4
 
5 5
 doc: cleandoc
6 6
 	doxygen
@@ -9,11 +9,13 @@ doc: cleandoc
9 9
 em_test:
10 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 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,7 +183,7 @@ class Reference(DataHandler):
183 183
 
184 184
     ## @brief Instanciation
185 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 187
     # @param internal bool : if False, the field is not internal
188 188
     # @param **kwargs : other arguments
189 189
     def __init__(self, allowed_classes = None, back_reference = None, internal=False, **kwargs):
@@ -191,12 +191,14 @@ class Reference(DataHandler):
191 191
         if back_reference is not None:
192 192
             if len(back_reference) != 2:
193 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 196
         self.__back_reference = back_reference
195 197
         super().__init__(internal=internal, **kwargs)
196 198
     
197 199
     @property
198 200
     def back_reference(self):
199
-        return self.__back_reference
201
+        return copy.copy(self.__back_reference)
200 202
 
201 203
     ## @brief Set the back reference for this field.
202 204
     def _set_back_reference(self, back_reference):

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

@@ -11,15 +11,6 @@ def dyncode_from_em(model):
11 11
     
12 12
     # Generation of LeObject child classes code
13 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 15
     # Header
25 16
     imports = """from lodel.leapi.leobject import LeObject
@@ -59,10 +50,20 @@ def data_handler_constructor(emfield):
59 50
     #dh_module_name = DataHandler.module_name(emfield.data_handler_name)+'.DataHandler'
60 51
     get_handler_class_instr = 'DataField.from_name(%s)' % repr(emfield.data_handler_name)
61 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 67
 def forge_optval(optval):
67 68
     if isinstance(optval, dict):
68 69
         return '{' + (', '.join( [ '%s: %s' % (repr(name), forge_optval(val)) for name, val in optval.items()])) + '}'
@@ -119,7 +120,6 @@ class {clsname}({parents}):
119 120
         res += em_cls_code
120 121
         # Dyncode bootstrap instructions
121 122
         bootstrap += """{classname}._set__fields({fields})
122
-#del({classname}._set__fields)
123 123
 """.format(
124 124
     classname = LeObject.name2objname(em_class.uid),
125 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,23 +157,6 @@ class LeObject(object):
157 157
         except AttributeError:
158 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 160
     @classmethod
178 161
     def is_abstract(cls):
179 162
         return cls._abstract

Loading…
Cancel
Save