From 0f2e7d783e77a07b440e7d6b16629e571376937d Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Thu, 4 Feb 2016 13:48:28 +0100 Subject: [PATCH] [FIX] fields: make `copy_cache` use a todo list instead of recursion The recursion was based on an incorrect assumption: the cache of the target environment is initially empty. If another computation left some value there, the copying is incomplete, and that causes bugs in onchanges. --- openerp/fields.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/openerp/fields.py b/openerp/fields.py index fc421fc1cc5..dedb49ef917 100644 --- a/openerp/fields.py +++ b/openerp/fields.py @@ -61,14 +61,17 @@ def _check_value(value): def copy_cache(records, env): """ Recursively copy the cache of ``records`` to the environment ``env``. """ - for record, target in zip(records, records.with_env(env)): - if not target._cache: + todo, done = set(records), set() + while todo: + record = todo.pop() + if record not in done: + done.add(record) + target = record.with_env(env) for name, value in record._cache.iteritems(): if isinstance(value, BaseModel): - target._cache[name] = value.with_env(env) - copy_cache(value, env) - else: - target._cache[name] = value + todo.add(value) + value = value.with_env(env) + target._cache[name] = value def resolve_all_mro(cls, name, reverse=False):