[FIX] translate,orm: remember local Model [_sql]_constraints, and keep only those...
authorOlivier Dony <odo@openerp.com>
Tue, 4 Dec 2012 08:29:47 +0000 (09:29 +0100)
committerOlivier Dony <odo@openerp.com>
Tue, 4 Dec 2012 08:29:47 +0000 (09:29 +0100)
Previously all _*constraints leaked upstream and
downstream, and were duplicated in all the exported
terms for all modules inheriting from a given model.

bzr revid: odo@openerp.com-20121204082947-tdpiu71ryxzuredb

openerp/osv/orm.py
openerp/tools/translate.py

index 3b9b8f3..110012b 100644 (file)
@@ -916,7 +916,16 @@ class BaseModel(object):
                     else:
                         new.extend(cls.__dict__.get(s, []))
                     nattr[s] = new
+
+                # Keep links to non-inherited constraints, e.g. useful when exporting translations
+                nattr['_local_constraints'] = cls.__dict__.get('_constraints', [])
+                nattr['_local_sql_constraints'] = cls.__dict__.get('_sql_constraints', [])
+
                 cls = type(name, (cls, parent_class), dict(nattr, _register=False))
+        else:
+            cls._local_constraints = getattr(cls, '_constraints', [])
+            cls._local_sql_constraints = getattr(cls, '_sql_constraints', [])
+
         if not getattr(cls, '_original_module', None):
             cls._original_module = cls._module
         obj = object.__new__(cls)
index 439cd50..0b600c7 100644 (file)
@@ -793,26 +793,33 @@ def trans_generate(lang, modules, cr):
     cr.execute(query_models, query_param)
 
     def push_constraint_msg(module, term_type, model, msg):
-        # Check presence of __call__ directly instead of using
-        # callable() because it will be deprecated as of Python 3.0
         if not hasattr(msg, '__call__'):
-            push_translation(module, term_type, model, 0, encode(msg))
-
+            push_translation(encode(module), term_type, encode(model), 0, encode(msg))
+
+    def push_local_constraints(module, model, cons_type='sql_constraints'):
+        """Climb up the class hierarchy and ignore inherited constraints
+           from other modules"""
+        term_type = 'sql_constraint' if cons_type == 'sql_constraints' else 'constraint'
+        msg_pos = 2 if cons_type == 'sql_constraints' else 1
+        for cls in model.__class__.__mro__:
+            if getattr(cls, '_module', None) != module:
+                continue
+            constraints = getattr(cls, '_local_' + cons_type, [])
+            for constraint in constraints:
+                push_constraint_msg(module, term_type, model._name, constraint[msg_pos])
+            
     for (_, model, module) in cr.fetchall():
-        module = encode(module)
-        model = encode(model)
-
         model_obj = pool.get(model)
 
         if not model_obj:
             _logger.error("Unable to find object %r", model)
             continue
 
-        for constraint in getattr(model_obj, '_constraints', []):
-            push_constraint_msg(module, 'constraint', model, constraint[1])
+        if model_obj._constraints:
+            push_local_constraints(module, model_obj, 'constraints')
 
-        for constraint in getattr(model_obj, '_sql_constraints', []):
-            push_constraint_msg(module, 'sql_constraint', model, constraint[2])
+        if model_obj._sql_constraints:
+            push_local_constraints(module, model_obj, 'sql_constraints')
 
     def get_module_from_path(path, mod_paths=None):
         if not mod_paths: