Merge commit 'origin/master' into mdv-gpl3-py26
[odoo/odoo.git] / bin / osv / orm.py
index cfc3111..92c29f1 100644 (file)
@@ -88,10 +88,10 @@ class browse_null(object):
         self.id = False
 
     def __getitem__(self, name):
-        return False
+        return None
 
     def __getattr__(self, name):
-        return False  # XXX: return self ?
+        return None  # XXX: return self ?
 
     def __int__(self):
         return False
@@ -155,7 +155,7 @@ class browse_record(object):
                 col = self._table._columns[name]
             elif name in self._table._inherit_fields:
                 col = self._table._inherit_fields[name][2]
-            elif hasattr(self._table, name):
+            elif hasattr(self._table, str(name)):
                 if isinstance(getattr(self._table, name), (types.MethodType, types.LambdaType, types.FunctionType)):
                     return lambda *args, **argv: getattr(self._table, name)(self._cr, self._uid, [self._id], *args, **argv)
                 else:
@@ -163,7 +163,7 @@ class browse_record(object):
             else:
                 logger = netsvc.Logger()
                 logger.notifyChannel('orm', netsvc.LOG_ERROR, "Programming error: field '%s' does not exist in object '%s' !" % (name, self._table._name))
-                return False
+                return None
 
             # if the field is a classic one or a many2one, we'll fetch all classic and many2one fields
             if col._classic_write:
@@ -191,6 +191,9 @@ class browse_record(object):
                                 d[n].set_value(self._cr, self._uid, d[n], self, f, lang_obj)
 
 
+           if not datas:
+                   # Where did those ids come from? Perhaps old entries in ir_model_data?
+                   raise except_orm('NoDataError', 'Field %s in %s%s'%(name,self._table_name,str(ids)))
             # create browse records for 'remote' objects
             for data in datas:
                 for n, f in ffields:
@@ -211,6 +214,12 @@ class browse_record(object):
                     elif f._type in ('one2many', 'many2many') and len(data[n]):
                         data[n] = self._list_class([browse_record(self._cr, self._uid, id, self._table.pool.get(f._obj), self._cache, context=self._context, list_class=self._list_class, fields_process=self._fields_process) for id in data[n]], self._context)
                 self._data[data['id']].update(data)
+       if not name in self._data[self._id]:
+               #how did this happen?
+               logger = netsvc.Logger()
+               logger.notifyChannel("browse_record", netsvc.LOG_ERROR,"Ffields: %s, datas: %s"%(str(fffields),str(datas)))
+               logger.notifyChannel("browse_record", netsvc.LOG_ERROR,"Data: %s, Table: %s"%(str(self._data[self._id]),str(self._table)))
+               raise AttributeError(_('Unknown attribute %s in %s ') % (str(name),self._table_name))
         return self._data[self._id][name]
 
     def __getattr__(self, name):
@@ -516,8 +525,10 @@ class orm_template(object):
                                 module, xml_id = current_module, line[i]
                             ir_model_data_obj = self.pool.get('ir.model.data')
                             id = ir_model_data_obj._get_id(cr, uid, module, xml_id)
-                            res_id = ir_model_data_obj.read(cr, uid, [id],
-                                    ['res_id'])[0]['res_id']
+                           res_res_id = ir_model_data_obj.read(cr, uid, [id],
+                                    ['res_id'])
+                           if res_res_id:
+                                   res_id = res_res_id[0]['res_id']
                     row[field[0][:-3]] = res_id or False
                     continue
                 if (len(field) == len(prefix)+1) and \
@@ -1021,7 +1032,7 @@ class orm_template(object):
                         if attr != 'position'
                     ])
                     tag = "<%s%s>" % (node2.localName, attrs)
-                    raise AttributeError(_("Couldn't find tag '%s' in parent view !") % tag)
+                    raise AttributeError(_("Couldn't find tag '%s' in parent view !\n%s") % (tag,src))
             return doc_src.toxml(encoding="utf-8").replace('\t', '')
 
         result = {'type': view_type, 'model': self._name}
@@ -1073,8 +1084,8 @@ class orm_template(object):
             # otherwise, build some kind of default view
             if view_type == 'form':
                 res = self.fields_get(cr, user, context=context)
-                xml = '''<?xml version="1.0" encoding="utf-8"?>''' \
-                '''<form string="%s">''' % (self._description,)
+                xml = '<?xml version="1.0" encoding="utf-8"?> ' \
+                     '<form string="%s">' % (self._description,)
                 for x in res:
                     if res[x]['type'] not in ('one2many', 'many2many'):
                         xml += '<field name="%s"/>' % (x,)
@@ -1085,19 +1096,25 @@ class orm_template(object):
                 _rec_name = self._rec_name
                 if _rec_name not in self._columns:
                     _rec_name = self._columns.keys()[0]
-                xml = '''<?xml version="1.0" encoding="utf-8"?>''' \
-                '''<tree string="%s"><field name="%s"/></tree>''' \
-                % (self._description, self._rec_name)
+                xml = '<?xml version="1.0" encoding="utf-8"?>' \
+                       '<tree string="%s"><field name="%s"/></tree>' \
+                       % (self._description, self._rec_name)
             elif view_type == 'calendar':
                 xml = self.__get_default_calendar_view()
             else:
-                xml = ''
+                xml = '<?xml version="1.0"?>'  # what happens here, graph case?
             result['arch'] = xml
             result['name'] = 'default'
             result['field_parent'] = False
             result['view_id'] = 0
 
-        doc = dom.minidom.parseString(encode(result['arch']))
+       try:
+               doc = dom.minidom.parseString(encode(result['arch']))
+       except Exception, ex:
+               logger = netsvc.Logger()
+               logger.notifyChannel('init', netsvc.LOG_DEBUG, 'Wrong arch in %s (%s):\n %s' % (result['name'], view_type, result['arch'] ))
+               raise except_orm('Error',
+                        ('Invalid xml in view %s(%d) of %s: %s' % (result['name'], result['view_id'], self._name, str(ex))))
         xarch, xfields = self.__view_look_dom_arch(cr, user, doc, view_id, context=context)
         result['arch'] = xarch
         result['fields'] = xfields
@@ -2679,13 +2696,14 @@ class orm(orm_template):
             elif ftype in ('one2many', 'one2one'):
                 res = []
                 rel = self.pool.get(fields[f]['relation'])
-                for rel_id in data[f]:
-                    # the lines are first duplicated using the wrong (old)
-                    # parent but then are reassigned to the correct one thanks
-                    # to the (4, ...)
-                    d,t = rel.copy_data(cr, uid, rel_id, context=context)
-                    res.append((0, 0, d))
-                    trans_data += t
+                if data[f] != False:
+                    for rel_id in data[f]:
+                        # the lines are first duplicated using the wrong (old)
+                        # parent but then are reassigned to the correct one thanks
+                        # to the (4, ...)
+                        d,t = rel.copy_data(cr, uid, rel_id, context=context)
+                        res.append((0, 0, d))
+                        trans_data += t
                 data[f] = res
             elif ftype == 'many2many':
                 data[f] = [(6, 0, data[f])]