[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.
This commit is contained in:
parent
67a63e2cc9
commit
0f2e7d783e
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue