diff options
| author | Christophe Simonis <chs@odoo.com> | 2017-08-24 13:17:53 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2017-08-24 13:17:53 +0200 |
| commit | 017ee5eab376b4f09beb62812c1cbc682009ed86 (patch) | |
| tree | 2af185b0604cd8ce9129c39137bbf39d21d7be89 /odoo/fields.py | |
| parent | 006c16198f7f68c9dc8b895defd013f33008840a (diff) | |
| parent | 877e7098719195ed2934fc9c3b5c3bd8ad8bab07 (diff) | |
[MERGE] forward port branch saas-17 up to 877e7098719
Diffstat (limited to 'odoo/fields.py')
| -rw-r--r-- | odoo/fields.py | 77 |
1 files changed, 38 insertions, 39 deletions
diff --git a/odoo/fields.py b/odoo/fields.py index 18174f1d145..43ee8edbad1 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -11,6 +11,7 @@ import itertools import logging import pytz + try: from xmlrpc.client import MAXINT except ImportError: @@ -19,12 +20,11 @@ except ImportError: import psycopg2 -from odoo.sql_db import LazyCursor -from odoo.tools import float_repr, float_round, frozendict, html_sanitize, human_size, pg_varchar, ustr, OrderedSet, pycompat -from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DATE_FORMAT -from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT as DATETIME_FORMAT -from odoo.tools.translate import html_translate, _ -import odoo.tools.sql as sql +from .sql_db import LazyCursor +from .tools import float_repr, float_round, frozendict, html_sanitize, human_size, pg_varchar, ustr, OrderedSet, pycompat, sql +from .tools import DEFAULT_SERVER_DATE_FORMAT as DATE_FORMAT +from .tools import DEFAULT_SERVER_DATETIME_FORMAT as DATETIME_FORMAT +from .tools.translate import html_translate, _ DATE_LENGTH = len(date.today().strftime(DATE_FORMAT)) DATETIME_LENGTH = len(datetime.now().strftime(DATETIME_FORMAT)) @@ -340,7 +340,7 @@ class Field(MetaField('DummyField', (object,), {})): def __init__(self, string=Default, **kwargs): kwargs['string'] = string self._sequence = kwargs['_sequence'] = next(_global_seq) - args = {key: val for key, val in pycompat.items(kwargs) if val is not Default} + args = {key: val for key, val in kwargs.items() if val is not Default} self.args = args or EMPTY_DICT self._setup_done = None @@ -369,7 +369,7 @@ class Field(MetaField('DummyField', (object,), {})): """ Set all field attributes at once (with slot defaults). """ # optimization: we assign slots only assign = object.__setattr__ - for key, val in pycompat.items(self._slots): + for key, val in self._slots.items(): assign(self, key, attrs.pop(key, val)) if attrs: assign(self, '_attrs', attrs) @@ -498,7 +498,7 @@ class Field(MetaField('DummyField', (object,), {})): def make_depends(deps): return tuple(deps(model) if callable(deps) else deps) - if isinstance(self.compute, basestring): + if isinstance(self.compute, pycompat.string_types): # if the compute method has been overridden, concatenate all their _depends self.depends = () for method in resolve_mro(model, self.compute, callable): @@ -517,7 +517,7 @@ class Field(MetaField('DummyField', (object,), {})): def _setup_related_full(self, model): """ Setup the attributes of a related field. """ # fix the type of self.related if necessary - if isinstance(self.related, basestring): + if isinstance(self.related, pycompat.string_types): self.related = tuple(self.related.split('.')) # determine the chain of fields, and make sure they are all set up @@ -547,7 +547,7 @@ class Field(MetaField('DummyField', (object,), {})): if not getattr(self, attr): setattr(self, attr, getattr(field, prop)) - for attr, value in pycompat.items(field._attrs): + for attr, value in field._attrs.items(): if attr not in self._attrs: setattr(self, attr, value) @@ -655,7 +655,7 @@ class Field(MetaField('DummyField', (object,), {})): model = model0.env.get(field.comodel_name) # add self's model dependencies - for mname, fnames in pycompat.items(model0._depends): + for mname, fnames in model0._depends.items(): model = model0.env[mname] for fname in fnames: field = model._fields[fname] @@ -745,9 +745,7 @@ class Field(MetaField('DummyField', (object,), {})): """ Convert ``value`` from the ``write`` format to the SQL format. """ if value is None or value is False: return None - if isinstance(value, unicode): - return value.encode('utf8') - return str(value) + return pycompat.to_native(value) def convert_to_cache(self, value, record, validate=True): """ Convert ``value`` to the cache format; ``value`` may come from an @@ -973,7 +971,7 @@ class Field(MetaField('DummyField', (object,), {})): for field in fields: for record in records: record._cache[field] = field.convert_to_cache(False, record, validate=False) - if isinstance(self.compute, basestring): + if isinstance(self.compute, pycompat.string_types): getattr(records, self.compute)() else: self.compute(records) @@ -1047,14 +1045,14 @@ class Field(MetaField('DummyField', (object,), {})): def determine_inverse(self, records): """ Given the value of ``self`` on ``records``, inverse the computation. """ - if isinstance(self.inverse, basestring): + if isinstance(self.inverse, pycompat.string_types): getattr(records, self.inverse)() else: self.inverse(records) def determine_domain(self, records, operator, value): """ Return a domain representing a condition on ``self``. """ - if isinstance(self.search, basestring): + if isinstance(self.search, pycompat.string_types): return getattr(records, self.search)(operator, value) else: return self.search(records, operator, value) @@ -1371,12 +1369,12 @@ class Char(_String): return None # we need to convert the string to a unicode object to be able # to evaluate its length (and possibly truncate it) reliably - return ustr(value)[:self.size].encode('utf8') + return pycompat.to_text(value)[:self.size] def convert_to_cache(self, value, record, validate=True): if value is None or value is False: return False - return ustr(value)[:self.size] + return pycompat.to_text(value)[:self.size] class Text(_String): @@ -1509,7 +1507,7 @@ class Date(Field): def convert_to_cache(self, value, record, validate=True): if not value: return False - if isinstance(value, basestring): + if isinstance(value, pycompat.string_types): if validate: # force parsing for validation self.from_string(value) @@ -1579,7 +1577,7 @@ class Datetime(Field): def convert_to_cache(self, value, record, validate=True): if not value: return False - if isinstance(value, basestring): + if isinstance(value, pycompat.string_types): if validate: # force parsing for validation self.from_string(value) @@ -1598,6 +1596,11 @@ class Datetime(Field): assert record, 'Record expected' return Datetime.to_string(Datetime.context_timestamp(record, Datetime.from_string(value))) +# http://initd.org/psycopg/docs/usage.html#binary-adaptation +# Received data is returned as buffer (in Python 2) or memoryview (in Python 3). +_BINARY = memoryview +if pycompat.PY2: + _BINARY = buffer #pylint: disable=buffer-builtin class Binary(Field): type = 'binary' @@ -1619,11 +1622,15 @@ class Binary(Field): # unicode in some circumstances, hence the str() cast here. # This str() coercion will only work for pure ASCII unicode strings, # on purpose - non base64 data must be passed as a 8bit byte strings. - return psycopg2.Binary(str(value)) if value else None + if not value: + return None + if isinstance(value, bytes): + return psycopg2.Binary(value) + return psycopg2.Binary(pycompat.text_type(value).encode('ascii')) def convert_to_cache(self, value, record, validate=True): - if isinstance(value, buffer): - return str(value) + if isinstance(value, _BINARY): + return bytes(value) if isinstance(value, pycompat.integer_types) and \ (record._context.get('bin_size') or record._context.get('bin_size_' + self.name)): @@ -1724,14 +1731,14 @@ class Selection(Field): if 'selection_add' in field.args: # use an OrderedDict to update existing values selection_add = field.args['selection_add'] - self.selection = list(pycompat.items(OrderedDict(self.selection + selection_add))) + self.selection = list(OrderedDict(self.selection + selection_add).items()) def _description_selection(self, env): """ return the selection list (pairs (value, label)); labels are translated according to context language """ selection = self.selection - if isinstance(selection, basestring): + if isinstance(selection, pycompat.string_types): return getattr(env[self.model_name], selection)() if callable(selection): return selection(env[self.model_name]) @@ -1748,7 +1755,7 @@ class Selection(Field): def get_values(self, env): """ return a list of the possible values """ selection = self.selection - if isinstance(selection, basestring): + if isinstance(selection, pycompat.string_types): selection = getattr(env[self.model_name], selection)() elif callable(selection): selection = selection(env[self.model_name]) @@ -1772,14 +1779,6 @@ class Selection(Field): return item[1] return False - def convert_to_column(self, value, record, values=None): - """ Convert ``value`` from the ``write`` format to the SQL format. """ - if value is None or value is False: - return None - if isinstance(value, unicode): - return value.encode('utf8') - return str(value) - class Reference(Selection): type = 'reference' @@ -1797,7 +1796,7 @@ class Reference(Selection): if isinstance(value, BaseModel): if not validate or (value._name in self.get_values(record.env) and len(value) <= 1): return process(value._name, value.id) if value else False - elif isinstance(value, basestring): + elif isinstance(value, pycompat.string_types): res_model, res_id = value.split(',') if record.env[res_model].browse(int(res_id)).exists(): return process(res_model, int(res_id)) @@ -1894,7 +1893,7 @@ class Many2one(_Relational): super(Many2one, self)._setup_attrs(model, name) # determine self.delegate if not self.delegate: - self.delegate = name in pycompat.values(model._inherits) + self.delegate = name in model._inherits.values() def update_db(self, model, columns): comodel = model.env[self.comodel_name] @@ -2117,7 +2116,7 @@ class _RelationalMulti(_Relational): self.depends += tuple( self.name + '.' + arg[0] for arg in self.domain - if isinstance(arg, (tuple, list)) and isinstance(arg[0], basestring) + if isinstance(arg, (tuple, list)) and isinstance(arg[0], pycompat.string_types) ) |
