From 9d4255e9e5a725b038bd6bfc9296aca5cf0e5747 Mon Sep 17 00:00:00 2001 From: Nicolas Bessi Date: Fri, 6 Jun 2014 11:51:21 +0200 Subject: [PATCH 1/4] [IMP] assertion on getter setter of recordset if it holds multiple records. An exception will be raised in order to ensure consitent behavior and avoid bug due to non explicit behavior. --- openerp/osv/fields2.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/openerp/osv/fields2.py b/openerp/osv/fields2.py index 6b06e0f4311ca..8a66eb40845b9 100644 --- a/openerp/osv/fields2.py +++ b/openerp/osv/fields2.py @@ -430,7 +430,9 @@ def __get__(self, record, owner): """ return the value of field `self` on `record` """ if record is None: return self # the field is accessed through the owner class - + if len(record) > 1: + raise Warning("Muliple records properties % may not be accessed" % + record) try: return record._cache[self] except KeyError: @@ -454,7 +456,8 @@ def __set__(self, record, value): """ set the value of field `self` on `record` """ if not record: raise Warning("Null record %s may not be assigned" % record) - + if len(record) > 1: + raise Warning("Muliple records % may not be assigned" % record) # only one record is updated env = record.env record = record[0] @@ -713,7 +716,7 @@ def context_today(record, timestamp=None): :param datetime timestamp: optional datetime value to use instead of the current date and time (must be a datetime, regular dates can't be converted between timezones.) - :rtype: str + :rtype: str """ today = timestamp or datetime.now() context_today = None From b41868a462536b0639c9ec595fbb040eaa4efcbe Mon Sep 17 00:00:00 2001 From: Nicolas Bessi Date: Fri, 6 Jun 2014 14:43:14 +0200 Subject: [PATCH 2/4] [IMP] adds new test to validate setter and getter behavior on recordset --- .../test_new_api/tests/test_new_fields.py | 22 ++++++++++++++++++- openerp/osv/fields2.py | 7 +++--- 2 files changed, 24 insertions(+), 5 deletions(-) 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 562fb9faa700e..f7c92b5c3198c 100644 --- a/openerp/addons/test_new_api/tests/test_new_fields.py +++ b/openerp/addons/test_new_api/tests/test_new_fields.py @@ -5,7 +5,7 @@ from collections import defaultdict from openerp.tests import common - +from openerp.exceptions import Warning class TestNewFields(common.TransactionCase): @@ -23,6 +23,26 @@ def test_00_basics(self): values = discussion.read(['name'])[0] self.assertEqual(values['name'], discussion.name) + def test_01_basic_set_assertion(self): + """ test item setter """ + record = self.env.ref('test_new_api.message_0_0') + self.assertEqual(len(record), 1) + record.body = 'OK' + records = self.env['test_new_api.message'].search([]) + assert len(records) > 1 + with self.assertRaises(Warning): + records.body = 'Faulty' + + def test_01_basic_get_assertion(self): + """ test item getter """ + record = self.env.ref('test_new_api.message_0_0') + self.assertEqual(len(record), 1) + ok = record.body + records = self.env['test_new_api.message'].search([]) + assert len(records) > 1 + with self.assertRaises(Warning): + faulty = records.body + def test_10_computed(self): """ check definition of computed fields """ # by default function fields are not stored and readonly diff --git a/openerp/osv/fields2.py b/openerp/osv/fields2.py index 8a66eb40845b9..5fc3374ee8225 100644 --- a/openerp/osv/fields2.py +++ b/openerp/osv/fields2.py @@ -431,8 +431,7 @@ def __get__(self, record, owner): if record is None: return self # the field is accessed through the owner class if len(record) > 1: - raise Warning("Muliple records properties % may not be accessed" % - record) + raise Warning("Muliple records properties %s may not be accessed" % record) try: return record._cache[self] except KeyError: @@ -455,9 +454,9 @@ def __get__(self, record, owner): def __set__(self, record, value): """ set the value of field `self` on `record` """ if not record: - raise Warning("Null record %s may not be assigned" % record) + raise Warning('Null record %s may not be assigned' % record) if len(record) > 1: - raise Warning("Muliple records % may not be assigned" % record) + raise Warning('Muliple records %s may not be assigned' % record) # only one record is updated env = record.env record = record[0] From e8423cf163eb574ff102a54fa91914233840993a Mon Sep 17 00:00:00 2001 From: "Nicolas Bessi (nbessi)" Date: Fri, 6 Jun 2014 15:18:58 +0200 Subject: [PATCH 3/4] Typo --- openerp/osv/fields2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/osv/fields2.py b/openerp/osv/fields2.py index 5fc3374ee8225..578e961c26935 100644 --- a/openerp/osv/fields2.py +++ b/openerp/osv/fields2.py @@ -431,7 +431,7 @@ def __get__(self, record, owner): if record is None: return self # the field is accessed through the owner class if len(record) > 1: - raise Warning("Muliple records properties %s may not be accessed" % record) + raise Warning("Multiple records properties %s may not be accessed" % record) try: return record._cache[self] except KeyError: @@ -456,7 +456,7 @@ def __set__(self, record, value): if not record: raise Warning('Null record %s may not be assigned' % record) if len(record) > 1: - raise Warning('Muliple records %s may not be assigned' % record) + raise Warning('Multiple records %s may not be assigned' % record) # only one record is updated env = record.env record = record[0] From 4161356c0fbae824ea430da9cc2631956aa6e97d Mon Sep 17 00:00:00 2001 From: "Nicolas Bessi (nbessi)" Date: Fri, 6 Jun 2014 15:23:42 +0200 Subject: [PATCH 4/4] Prevent crash due to API consolidation Courtesy of @florentx --- openerp/addons/base/res/res_currency.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/res/res_currency.py b/openerp/addons/base/res/res_currency.py index daabbef0eb0cb..6aca06e62f1d8 100644 --- a/openerp/addons/base/res/res_currency.py +++ b/openerp/addons/base/res/res_currency.py @@ -116,7 +116,7 @@ def init(self, cr): @api.one @api.depends('rate_ids.name') def compute_date(self): - self.date = self.rate_ids.name + self.date = self.rate_ids[0].name if self.rate_ids else False def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100): if not args: