[FIX] tools: serialize lazy to json
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from collections import defaultdict
|
||||
import json
|
||||
|
||||
from odoo.tests.common import TransactionCase, users, warmup
|
||||
from odoo.tools import pycompat
|
||||
@@ -138,3 +139,6 @@ class TestPerformance(TransactionCase):
|
||||
self.assertEqual(res['partner_id'][0], exp['partner_id'][0])
|
||||
self.assertEqual(res['partner_id_count'], exp['partner_id_count'])
|
||||
self.assertEqual(res['value'], exp['value'])
|
||||
# now serialize to json, which should force evaluation
|
||||
with self.assertQueryCount(admin=1, demo=1):
|
||||
json.dumps(result)
|
||||
|
||||
+30
-18
@@ -4,8 +4,9 @@
|
||||
__all__ = ['synchronized', 'lazy_classproperty', 'lazy_property',
|
||||
'classproperty', 'conditional', 'lazy']
|
||||
|
||||
from functools import wraps, partial
|
||||
from functools import wraps
|
||||
from inspect import getsourcefile
|
||||
from json import JSONEncoder
|
||||
|
||||
|
||||
class lazy_property(object):
|
||||
@@ -122,27 +123,27 @@ class lazy(object):
|
||||
baz = foo + 2 # use result of func(arg) and add 2
|
||||
|
||||
"""
|
||||
__slots__ = ['_func', '_value']
|
||||
__slots__ = ['_func', '_args', '_kwargs', '_cached_value']
|
||||
|
||||
def __init__(self, func, *args, **kwargs):
|
||||
self._func = partial(func, *args, **kwargs)
|
||||
# bypass own __setattr__
|
||||
object.__setattr__(self, '_func', func)
|
||||
object.__setattr__(self, '_args', args)
|
||||
object.__setattr__(self, '_kwargs', kwargs)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == '_value':
|
||||
self._value = value = self._func()
|
||||
self._func = None
|
||||
return value
|
||||
return getattr(self._value, name)
|
||||
@property
|
||||
def _value(self):
|
||||
if self._func is not None:
|
||||
value = self._func(*self._args, **self._kwargs)
|
||||
object.__setattr__(self, '_func', None)
|
||||
object.__setattr__(self, '_args', None)
|
||||
object.__setattr__(self, '_kwargs', None)
|
||||
object.__setattr__(self, '_cached_value', value)
|
||||
return self._cached_value
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name in ('_func', '_value'):
|
||||
return object.__setattr__(self, name, value)
|
||||
return setattr(self._value, name, value)
|
||||
|
||||
def __delattr__(self, name):
|
||||
if name in ('_func', '_value'):
|
||||
return object.__delattr__(self, name)
|
||||
return delattr(self._value, name)
|
||||
def __getattr__(self, name): return getattr(self._value, name)
|
||||
def __setattr__(self, name, value): return setattr(self._value, name, value)
|
||||
def __delattr__(self, name): return delattr(self._value, name)
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self._value) if self._func is None else object.__repr__(self)
|
||||
@@ -241,3 +242,14 @@ class lazy(object):
|
||||
def __aenter__(self): return self._value.__aenter__()
|
||||
def __aexit__(self, exc_type, exc_value, traceback):
|
||||
return self._value.__aexit__(exc_type, exc_value, traceback)
|
||||
|
||||
|
||||
# patch serialization of lazy
|
||||
def default(self, o):
|
||||
if isinstance(o, lazy):
|
||||
return o._value
|
||||
return json_encoder_default(self, o)
|
||||
|
||||
|
||||
json_encoder_default = JSONEncoder.default
|
||||
JSONEncoder.default = default
|
||||
|
||||
Reference in New Issue
Block a user