summaryrefslogtreecommitdiff
path: root/odoo/api.py
diff options
context:
space:
mode:
Diffstat (limited to 'odoo/api.py')
-rw-r--r--odoo/api.py45
1 files changed, 38 insertions, 7 deletions
diff --git a/odoo/api.py b/odoo/api.py
index 68b92943640..cf56718b032 100644
--- a/odoo/api.py
+++ b/odoo/api.py
@@ -452,6 +452,7 @@ class Environment(Mapping):
self.cr, self.uid, self.context, self.su = self.args = args
self.registry = Registry(cr.dbname)
self.cache = envs.cache
+ self._cache_key = {} # memo {field: cache_key}
self._protected = envs.protected # proxy to shared data structure
self.all = envs
envs.add(self)
@@ -709,6 +710,36 @@ class Environment(Mapping):
""" Delay recomputations (deprecated: this is not the default behavior). """
yield
+ def cache_key(self, field):
+ """ Return the cache key corresponding to ``field.depends_context``. """
+ try:
+ return self._cache_key[field]
+
+ except KeyError:
+ def get(key, get_context=self.context.get):
+ if key == 'company':
+ return self.company.id
+ elif key == 'uid':
+ return (self.uid, self.su)
+ elif key == 'active_test':
+ return get_context('active_test', field.context.get('active_test', True))
+ else:
+ val = get_context(key)
+ try:
+ hash(val)
+ except TypeError:
+ raise TypeError(
+ "Can only create cache keys from hashable values, "
+ "got non-hashable value {!r} at context key {!r} "
+ "(dependency of field {})".format(val, key, field)
+ ) from None # we don't need to chain the exception created 2 lines above
+ else:
+ return val
+
+ result = tuple(get(key) for key in field.depends_context)
+ self._cache_key[field] = result
+ return result
+
class Environments(object):
""" A common object for all environments in a request. """
@@ -742,7 +773,7 @@ class Cache(object):
def contains(self, record, field):
""" Return whether ``record`` has a value for ``field``. """
if field.depends_context:
- key = field.cache_key(record.env)
+ key = record.env.cache_key(field)
return key in self._data.get(field, {}).get(record.id, {})
return record.id in self._data.get(field, ())
@@ -751,7 +782,7 @@ class Cache(object):
try:
value = self._data[field][record._ids[0]]
if field.depends_context:
- value = value[field.cache_key(record.env)]
+ value = value[record.env.cache_key(field)]
return value
except KeyError:
if default is NOTHING:
@@ -761,7 +792,7 @@ class Cache(object):
def set(self, record, field, value):
""" Set the value of ``field`` for ``record``. """
if field.depends_context:
- key = field.cache_key(record.env)
+ key = record.env.cache_key(field)
self._data[field].setdefault(record._ids[0], {})[key] = value
else:
self._data[field][record._ids[0]] = value
@@ -769,7 +800,7 @@ class Cache(object):
def update(self, records, field, values):
""" Set the values of ``field`` for several ``records``. """
if field.depends_context:
- key = field.cache_key(records.env)
+ key = records.env.cache_key(field)
field_cache = self._data[field]
for record_id, value in zip(records._ids, values):
field_cache.setdefault(record_id, {})[key] = value
@@ -786,7 +817,7 @@ class Cache(object):
def get_values(self, records, field):
""" Return the cached values of ``field`` for ``records``. """
field_cache = self._data[field]
- key = field.cache_key(records.env) if field.depends_context else None
+ key = records.env.cache_key(field) if field.depends_context else None
for record_id in records._ids:
try:
if key is not None:
@@ -799,7 +830,7 @@ class Cache(object):
def get_records_different_from(self, records, field, value):
""" Return the subset of ``records`` that has not ``value`` for ``field``. """
field_cache = self._data[field]
- key = field.cache_key(records.env) if field.depends_context else None
+ key = records.env.cache_key(field) if field.depends_context else None
ids = []
for record_id in records._ids:
try:
@@ -822,7 +853,7 @@ class Cache(object):
values = self._data.get(field, {})
if record.id not in values:
continue
- if field.depends_context and field.cache_key(record.env) not in values[record.id]:
+ if field.depends_context and record.env.cache_key(field) not in values[record.id]:
continue
yield field