diff --git a/openerp/addons/test_new_api/tests/test_new_fields.py b/openerp/addons/test_new_api/tests/test_new_fields.py index 7ca55c4eabd..323c2c2c31d 100644 --- a/openerp/addons/test_new_api/tests/test_new_fields.py +++ b/openerp/addons/test_new_api/tests/test_new_fields.py @@ -131,6 +131,26 @@ class TestNewFields(common.TransactionCase): }) check_stored(discussion3) + def test_11_computed_access(self): + """ test computed fields with access right errors """ + User = self.env['res.users'] + user1 = User.create({'name': 'Aaaah', 'login': 'a'}) + user2 = User.create({'name': 'Boooh', 'login': 'b'}) + user3 = User.create({'name': 'Crrrr', 'login': 'c'}) + # add a rule to not give access to user2 + self.env['ir.rule'].create({ + 'model_id': self.env['ir.model'].search([('model', '=', 'res.users')]).id, + 'domain_force': "[('id', '!=', %d)]" % user2.id, + }) + # group users as a recordset, and read them as user demo + users = (user1 + user2 + user3).sudo(self.env.ref('base.user_demo')) + user1, user2, user3 = users + # regression test: a bug invalidated the field's value from cache + user1.company_type + with self.assertRaises(AccessError): + user2.company_type + user3.company_type + def test_12_recursive(self): """ test recursively dependent fields """ Category = self.env['test_new_api.category'] diff --git a/openerp/fields.py b/openerp/fields.py index ed536c82ff6..60f5d7fa69a 100644 --- a/openerp/fields.py +++ b/openerp/fields.py @@ -884,21 +884,21 @@ class Field(object): def _compute_value(self, records): """ Invoke the compute method on ``records``. """ # initialize the fields to their corresponding null value in cache - computed = records._field_computed[self] - for field in computed: + for field in records._field_computed[self]: for record in records: record._cache[field] = field.convert_to_cache(False, record, validate=False) - records.env.computed[field].update(records._ids) if isinstance(self.compute, basestring): getattr(records, self.compute)() else: self.compute(records) - for field in computed: - records.env.computed[field].difference_update(records._ids) def compute_value(self, records): """ Invoke the compute method on ``records``; the results are in cache. """ with records.env.do_in_draft(): + saved = {} + for field in records._field_computed[self]: + ids = saved[field] = records.env.computed[field] + records.env.computed[field] = ids.union(records._ids) try: self._compute_value(records) except (AccessError, MissingError): @@ -908,6 +908,8 @@ class Field(object): self._compute_value(record) except Exception as exc: record._cache[self.name] = FailedValue(exc) + finally: + records.env.computed.update(saved) def determine_value(self, record): """ Determine the value of ``self`` for ``record``. """