From b624267457f8d0c8a0db6ddc554f29409666ee88 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 4 Dec 2012 09:29:47 +0100 Subject: [PATCH] [FIX] translate,orm: remember local Model [_sql]_constraints, and keep only those when exporting translations 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 | 9 +++++++++ openerp/tools/translate.py | 27 +++++++++++++++++---------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 3b9b8f30d23..110012bbc07 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -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) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 439cd508122..0b600c75933 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -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: