Open sveneberth opened 6 months ago
Solved by #1093
Hey @ArneGudermann,
I tested it again and found a confusing behaivior.
I have this bone (has row=True
by default):
price = JsonBone(
compute=Compute(lambda skel: skel.price_.to_dict(), ComputeInterval(ComputeMethod.Always))
)
This will use JsonBone.singleValueUnserialize
which tries to load a json string and fails (it's a dict):
[2024-09-03 16:49:37,983] /.../viur/core/request.py:332 [ERROR] the JSON object must be str, bytes or bytearray, not dict
Traceback (most recent call last):
File "/.../viur-core/src/viur/core/request.py", line 306, in _process
self._route(path)
File "/.../viur-core/src/viur/core/request.py", line 565, in _route
res = caller(*self.args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../viur-core/src/viur/core/module.py", line 299, in __call__
return self._func(self._instance, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../viur-shop/src/viur/shop/modules/api.py", line 272, in cart_list
child = self.json_renderer.renderSkelValues(child_skel)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../viur-core/src/viur/core/render/json/default.py", line 137, in renderSkelValues
res[key] = self.renderBoneValue(bone, skel, key)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../viur-core/src/viur/core/render/json/default.py", line 102, in renderBoneValue
boneVal = skel[key]
~~~~^^^^^
File "/.../viur-core/src/viur/core/skeleton.py", line 226, in __getitem__
boneInstance.unserialize(self, key)
File "/.../viur-core/src/viur/core/bones/base.py", line 815, in unserialize
skel.accessedValues[name] = self._compute(skel, name)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../viur-core/src/viur/core/bones/base.py", line 1295, in _compute
return unserialize_raw_value(ret)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../viur-core/src/viur/core/bones/base.py", line 1287, in unserialize_raw_value
return self.singleValueUnserialize(raw_value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.../viur-core/src/viur/core/bones/json.py", line 49, in singleValueUnserialize
return utils.json.loads(val)
^^^^^^^^^^^^^^^^^^^^^
File "/.../viur-core/src/viur/core/utils/json.py", line 90, in loads
return json.loads(s, object_hook=object_hook, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/json/__init__.py", line 339, in loads
raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not dict
So it failes to keep the raw value as it is.
With raw=False
it works, because fromClient
can handle the dict.
price = JsonBone(
compute=Compute(lambda skel: skel.price_.to_dict(), ComputeInterval(ComputeMethod.Always), raw=False)
)
I think raw: True
should work, what do u think?
Mhh maybe we can add a check for this like:
def singleValueUnserialize(self, val):
if isinstance(val, (str,bytes,bytearray)):
return utils.json.loads(val)
return utils.json.loads(utils.json.dumps(val))
or
def singleValueUnserialize(self, val):
if isinstance(val, (str,bytes,bytearray)):
return utils.json.loads(val)
return val
compute
is implemented inserialize
andunserialize
, but theJsonBone
overwrites this without a super call. Sobone._compute
is never called and the bone value isNone
.