From 282fc4a8505fba146b65cd484d35123b7de3bc96 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Fri, 10 Jul 2015 10:23:41 +0200 Subject: [PATCH] [FIX] openerp: export empty string instead of None xmlrpc 1.0 does not support None/null, so commit f3e4d0a will break xmlrpc api. Therefore, we export an empty string if the field is empty, instead of False or None. For integers and floats, zero is exported. opw-643966 --- .../addons/test_impex/tests/test_export.py | 22 +++++----- openerp/fields.py | 41 +++++++++++-------- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/openerp/addons/test_impex/tests/test_export.py b/openerp/addons/test_impex/tests/test_export.py index 49a16387a3a..26f39db62e5 100644 --- a/openerp/addons/test_impex/tests/test_export.py +++ b/openerp/addons/test_impex/tests/test_export.py @@ -49,7 +49,7 @@ class test_integer_field(CreatorCase): def test_0(self): self.assertEqual( self.export(0), - [[False]]) + [[u'0']]) def test_basic_value(self): self.assertEqual( @@ -72,7 +72,7 @@ class test_float_field(CreatorCase): def test_0(self): self.assertEqual( self.export(0.0), - [[False]]) + [[u'0.0']]) def test_epsilon(self): self.assertEqual( @@ -100,14 +100,14 @@ class test_decimal_field(CreatorCase): def test_0(self): self.assertEqual( self.export(0.0), - [[False]]) + [[u'0.0']]) def test_epsilon(self): """ epsilon gets sliced to 0 due to precision """ self.assertEqual( self.export(0.000000000027), - [[False]]) + [[u'0.0']]) def test_negative(self): self.assertEqual( @@ -129,7 +129,7 @@ class test_string_field(CreatorCase): def test_empty(self): self.assertEqual( self.export(""), - [[False]]) + [['']]) def test_within_bounds(self): self.assertEqual( self.export("foobar"), @@ -148,7 +148,7 @@ class test_unbound_string_field(CreatorCase): def test_empty(self): self.assertEqual( self.export(""), - [[False]]) + [['']]) def test_small(self): self.assertEqual( self.export("foobar"), @@ -170,7 +170,7 @@ class test_text(CreatorCase): def test_empty(self): self.assertEqual( self.export(""), - [[False]]) + [['']]) def test_small(self): self.assertEqual( self.export("foobar"), @@ -190,7 +190,7 @@ class test_date(CreatorCase): def test_empty(self): self.assertEqual( self.export(False), - [[False]]) + [['']]) def test_basic(self): self.assertEqual( self.export('2011-11-07'), @@ -202,7 +202,7 @@ class test_datetime(CreatorCase): def test_empty(self): self.assertEqual( self.export(False), - [[False]]) + [['']]) def test_basic(self): self.assertEqual( self.export('2011-11-07 21:05:48'), @@ -265,7 +265,7 @@ class test_selection_function(CreatorCase): def test_empty(self): self.assertEqual( self.export(False), - [[None]]) + [['']]) def test_value(self): # FIXME: selection functions export the *value* itself @@ -278,7 +278,7 @@ class test_selection_function(CreatorCase): # fucking hell self.assertEqual( self.export(0), - [[None]]) + [['']]) class test_m2o(CreatorCase): model_name = 'export.many2one' diff --git a/openerp/fields.py b/openerp/fields.py index ca605dff0f2..9c6187894ce 100644 --- a/openerp/fields.py +++ b/openerp/fields.py @@ -781,9 +781,9 @@ class Field(object): """ convert ``value`` from the cache to a valid value for export. The parameter ``env`` is given for managing translations. """ - if env.context.get('export_raw_data'): - return value - return bool(value) and ustr(value) + if not value: + return '' + return value if env.context.get('export_raw_data') else ustr(value) def convert_to_display_name(self, value, record=None): """ convert ``value`` from the cache to a suitable display name. """ @@ -1035,6 +1035,11 @@ class Integer(Field): # special case, when an integer field is used as inverse for a one2many records._cache[self] = value.id or 0 + def convert_to_export(self, value, env): + if value or value == 0: + return value if env.context.get('export_raw_data') else ustr(value) + return '' + class Float(Field): """ The precision digits are given by the attribute @@ -1082,6 +1087,11 @@ class Float(Field): digits = self.digits return float_round(value, precision_digits=digits[1]) if digits else value + def convert_to_export(self, value, env): + if value or value == 0.0: + return value if env.context.get('export_raw_data') else ustr(value) + return '' + class _String(Field): """ Abstract class for string fields. """ @@ -1093,11 +1103,6 @@ class _String(Field): _related_translate = property(attrgetter('translate')) _description_translate = property(attrgetter('translate')) - def convert_to_export(self, value, env): - if env.context.get('export_raw_data'): - return value if value else None - return bool(value) and ustr(value) - class Char(_String): """ Basic string field, can be length-limited, usually displayed as a @@ -1216,9 +1221,9 @@ class Date(Field): return self.to_string(value) def convert_to_export(self, value, env): - if value and env.context.get('export_raw_data'): - return self.from_string(value) or None - return bool(value) and ustr(value) + if not value: + return '' + return self.from_string(value) if env.context.get('export_raw_data') else ustr(value) class Datetime(Field): @@ -1285,9 +1290,9 @@ class Datetime(Field): return self.to_string(value) def convert_to_export(self, value, env): - if value and env.context.get('export_raw_data'): - return self.from_string(value) or None - return bool(value) and ustr(value) + if not value: + return '' + return self.from_string(value) if env.context.get('export_raw_data') else ustr(value) def convert_to_display_name(self, value, record=None): assert record, 'Record expected' @@ -1395,7 +1400,7 @@ class Selection(Field): def convert_to_export(self, value, env): if not isinstance(self.selection, list): # FIXME: this reproduces an existing buggy behavior! - return value or None + return value if value else '' for item in self._description_selection(env): if item[0] == value: return item[1] @@ -1432,7 +1437,7 @@ class Reference(Selection): return "%s,%s" % (value._name, value.id) if value else False def convert_to_export(self, value, env): - return value.name_get()[0][1] if value else None + return value.name_get()[0][1] if value else '' def convert_to_display_name(self, value, record=None): return ustr(value and value.display_name) @@ -1572,7 +1577,7 @@ class Many2one(_Relational): return value.id def convert_to_export(self, value, env): - return value.name_get()[0][1] if value else None + return value.name_get()[0][1] if value else '' def convert_to_display_name(self, value, record=None): return ustr(value.display_name) @@ -1678,7 +1683,7 @@ class _RelationalMulti(_Relational): return result def convert_to_export(self, value, env): - return ','.join(name for id, name in value.name_get()) if value else None + return ','.join(name for id, name in value.name_get()) if value else '' def convert_to_display_name(self, value, record=None): raise NotImplementedError()