[CHG] core: move traverse_container out of utils

It's really not a general purpose utility, it's just a way of forcing
a lazy collection's evaluation.

Alternatively, add a helper for this to / alongside `lazy`? Note that
the lazy object(s) may not be the top-level.

closes odoo/odoo#98023

Related: odoo/upgrade#3776
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is contained in:
Xavier Morel
2022-08-22 16:48:28 +02:00
parent 7f14631fe8
commit 4cd0119eff
2 changed files with 26 additions and 28 deletions
+26 -9
View File
@@ -1,23 +1,21 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from functools import partial
import json
import logging
from psycopg2 import IntegrityError, OperationalError, errorcodes
import random
import threading
import time
from collections.abc import Mapping, Sequence
from functools import partial
from psycopg2 import IntegrityError, OperationalError, errorcodes
import odoo
from odoo.exceptions import UserError, ValidationError
from odoo.http import request
from odoo.models import check_method_name
from odoo.tools import DotDict
from odoo.tools.translate import translate_sql_constraint
from odoo.tools.translate import _
from odoo.tools.translate import _, translate_sql_constraint
from . import security
from ..tools import traverse_containers, lazy
from ..tools import lazy
_logger = logging.getLogger(__name__)
@@ -52,7 +50,7 @@ def execute_cr(cr, uid, obj, method, *args, **kw):
result = retrying(partial(odoo.api.call_kw, recs, method, args, kw), env)
# force evaluation of lazy values before the cursor is closed, as it would
# error afterwards if the lazy isn't already evaluated (and cached)
for l in traverse_containers(result, lazy):
for l in _traverse_containers(result, lazy):
_0 = l._value
return result
@@ -167,3 +165,22 @@ def retrying(func, env):
env.cr.commit() # effectively commits and execute post-commits
env.registry.signal_changes()
return result
def _traverse_containers(val, type_):
""" Yields atoms filtered by specified ``type_`` (or type tuple), traverses
through standard containers (non-string mappings or sequences) *unless*
they're selected by the type filter
"""
from odoo.models import BaseModel
if isinstance(val, type_):
yield val
elif isinstance(val, (str, bytes, BaseModel)):
return
elif isinstance(val, Mapping):
for k, v in val.items():
yield from _traverse_containers(k, type_)
yield from _traverse_containers(v, type_)
elif isinstance(val, Sequence):
for v in val:
yield from _traverse_containers(v, type_)
-19
View File
@@ -1638,25 +1638,6 @@ def get_diff(data_from, data_to, custom_style=False):
return handle_style(diff, custom_style)
def traverse_containers(val, type_):
""" Yields atoms filtered by specified ``type_`` (or type tuple), traverses
through standard containers (non-string mappings or sequences) *unless*
they're selected by the type filter
"""
from odoo.models import BaseModel
if isinstance(val, type_):
yield val
elif isinstance(val, (str, bytes, BaseModel)):
return
elif isinstance(val, Mapping):
for k, v in val.items():
yield from traverse_containers(k, type_)
yield from traverse_containers(v, type_)
elif isinstance(val, collections.abc.Sequence):
for v in val:
yield from traverse_containers(v, type_)
def hmac(env, scope, message, hash_function=hashlib.sha256):
"""Compute HMAC with `database.secret` config parameter as key.