[FIX] Marshall frozendict in XMLRPC controller

PR #42723 changed the public method context_get on res.users return a
frozendict instead of a classic CPython dict.

Since the default XMLRPC Marshaller does not know how to serialize a
frozendict, this would result in errors when calling the method directly
via the XMLRPC layer.

This commit solves this issue by defining a marshalling procedure for
frozendict objects in our custom OdooMarshaller class, this simply
converts the frozendict into a dict and uses the default dict-to-xml
dump procedure (dump_struct).

Fixes #75412

closes odoo/odoo#75478

X-original-commit: e80a299ed910cacac4aa4e64164909af36ce62ad
Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
This commit is contained in:
Florent THOMAS
2021-08-24 06:32:51 +00:00
committed by Adrian Torres
parent e8f8939db7
commit 56ca5e9297
2 changed files with 15 additions and 0 deletions
+6
View File
@@ -9,6 +9,7 @@ from odoo.http import Controller, dispatch_rpc, request, route
from odoo.service import wsgi_server
from odoo.fields import Date, Datetime, Command
from odoo.tools import lazy
from odoo.tools.misc import frozendict
class OdooMarshaller(xmlrpc.client.Marshaller):
@@ -19,6 +20,11 @@ class OdooMarshaller(xmlrpc.client.Marshaller):
dispatch = dict(xmlrpc.client.Marshaller.dispatch)
def dump_frozen_dict(self, value, write):
value = dict(value)
self.dump_struct(value, write)
dispatch[frozendict] = dump_frozen_dict
def dump_datetime(self, value, write):
# override to marshall as a string for backwards compatibility
value = Datetime.to_string(value)
+9
View File
@@ -62,6 +62,15 @@ class TestXMLRPC(common.HttpCase):
[x] = self.xmlrpc('res.users', 'read', r.id, ['signature'])
self.assertEqual(x['signature'], sig)
def test_xmlrpc_frozendict_marshalling(self):
""" Test that the marshalling of a frozendict object works properly over XMLRPC """
ctx = self.xmlrpc_object.execute(
common.get_db_name(), self.admin_uid, 'admin',
'res.users', 'context_get',
)
self.assertEqual(ctx['lang'], 'en_US')
self.assertEqual(ctx['tz'], 'Europe/Brussels')
def test_jsonrpc_read_group(self):
self._json_call(
common.get_db_name(), self.admin_uid, 'admin',