summaryrefslogtreecommitdiff
path: root/odoo
diff options
context:
space:
mode:
authorRaphael Collet <rco@odoo.com>2019-02-14 12:59:04 +0000
committerRaphael Collet <rco@odoo.com>2019-03-22 16:42:14 +0000
commitd87443a21337bcc3d785ae23e19f66b11ba8bb9e (patch)
tree0a10e803beca0026560ecb32c18b492c7323de22 /odoo
parent1ced3bfca457ac50845637bcd42a8e53bd7f088d (diff)
[FIX] convert: enable kwargs in tag <function>
closes odoo/odoo#31417 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Diffstat (limited to 'odoo')
-rw-r--r--odoo/addons/test_convert/__init__.py12
-rw-r--r--odoo/addons/test_convert/models.py20
-rw-r--r--odoo/addons/test_convert/tests/test_convert.py114
-rw-r--r--odoo/import_xml.rng1
-rw-r--r--odoo/tools/convert.py36
5 files changed, 151 insertions, 32 deletions
diff --git a/odoo/addons/test_convert/__init__.py b/odoo/addons/test_convert/__init__.py
index a301ab24b52..dc5e6b693d1 100644
--- a/odoo/addons/test_convert/__init__.py
+++ b/odoo/addons/test_convert/__init__.py
@@ -1,10 +1,4 @@
-from odoo import fields, models
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-class Usered(models.Model):
- _name = 'test_convert.usered'
- _description = "z test model ignore"
-
- name = fields.Char()
- user_id = fields.Many2one('res.users', default=lambda self: self.env.user)
- tz = fields.Char(default=lambda self: self.env.context.get('tz') or self.env.user.tz)
+from . import models
diff --git a/odoo/addons/test_convert/models.py b/odoo/addons/test_convert/models.py
new file mode 100644
index 00000000000..e48ac2d1e7f
--- /dev/null
+++ b/odoo/addons/test_convert/models.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import models, fields, api
+
+
+class Usered(models.Model):
+ _name = 'test_convert.usered'
+ _description = "z test model ignore"
+
+ name = fields.Char()
+ user_id = fields.Many2one('res.users', default=lambda self: self.env.user)
+ tz = fields.Char(default=lambda self: self.env.context.get('tz') or self.env.user.tz)
+
+ @api.model
+ def model_method(self, *args, **kwargs):
+ return self, args, kwargs
+
+ def method(self, *args, **kwargs):
+ return self, args, kwargs
diff --git a/odoo/addons/test_convert/tests/test_convert.py b/odoo/addons/test_convert/tests/test_convert.py
index e81526dd43c..709a5eeab10 100644
--- a/odoo/addons/test_convert/tests/test_convert.py
+++ b/odoo/addons/test_convert/tests/test_convert.py
@@ -7,7 +7,7 @@ import unittest
from lxml.builder import E
from odoo.tests import common
-from odoo.tools.convert import _eval_xml
+from odoo.tools.convert import xml_import, _eval_xml
Field = E.field
Value = E.value
@@ -74,6 +74,118 @@ class TestEvalXML(common.TransactionCase):
with self.assertRaises(IOError):
self.eval_xml(Field('test_nofile.txt', type='file'), obj)
+ def test_function(self):
+ obj = xml_import(self.cr, 'test_convert', None, 'init')
+
+ # pass args in eval
+ xml = E.function(
+ model="test_convert.usered",
+ name="model_method",
+ eval="[1, 2]",
+ )
+ rec, args, kwargs = self.eval_xml(xml, obj)
+ self.assertEqual(rec.env.context, self.env.context)
+ self.assertEqual(rec.ids, [])
+ self.assertEqual(args, (1, 2))
+ self.assertEqual(kwargs, {})
+
+ xml = E.function(
+ model="test_convert.usered",
+ name="method",
+ eval="[1, 2]",
+ )
+ rec, args, kwargs = self.eval_xml(xml, obj)
+ self.assertEqual(rec.env.context, self.env.context)
+ self.assertEqual(rec.ids, [1])
+ self.assertEqual(args, (2,))
+ self.assertEqual(kwargs, {})
+
+ # pass args in child elements
+ xml = E.function(
+ E.value(eval="1"), E.value(eval="2"),
+ model="test_convert.usered",
+ name="model_method",
+ )
+ rec, args, kwargs = self.eval_xml(xml, obj)
+ self.assertEqual(rec.env.context, self.env.context)
+ self.assertEqual(rec.ids, [])
+ self.assertEqual(args, (1, 2))
+ self.assertEqual(kwargs, {})
+
+ xml = E.function(
+ E.value(eval="1"), E.value(eval="2"),
+ model="test_convert.usered",
+ name="method",
+ )
+ rec, args, kwargs = self.eval_xml(xml, obj)
+ self.assertEqual(rec.env.context, self.env.context)
+ self.assertEqual(rec.ids, [1])
+ self.assertEqual(args, (2,))
+ self.assertEqual(kwargs, {})
+
+ def test_function_kwargs(self):
+ obj = xml_import(self.cr, 'test_convert', None, 'init')
+
+ # pass args and kwargs in child elements
+ xml = E.function(
+ E.value(eval="1"), E.value(name="foo", eval="2"),
+ model="test_convert.usered",
+ name="model_method",
+ )
+ rec, args, kwargs = self.eval_xml(xml, obj)
+ self.assertEqual(rec.env.context, self.env.context)
+ self.assertEqual(rec.ids, [])
+ self.assertEqual(args, (1,))
+ self.assertEqual(kwargs, {'foo': 2})
+
+ xml = E.function(
+ E.value(eval="1"), E.value(name="foo", eval="2"),
+ model="test_convert.usered",
+ name="method",
+ )
+ rec, args, kwargs = self.eval_xml(xml, obj)
+ self.assertEqual(rec.env.context, self.env.context)
+ self.assertEqual(rec.ids, [1])
+ self.assertEqual(args, ())
+ self.assertEqual(kwargs, {'foo': 2})
+
+ # pass args and context in kwargs
+ xml = E.function(
+ E.value(eval="1"), E.value(name="context", eval="{'foo': 2}"),
+ model="test_convert.usered",
+ name="model_method",
+ )
+ rec, args, kwargs = self.eval_xml(xml, obj)
+ self.assertEqual(rec.env.context, {'foo': 2})
+ self.assertEqual(rec.ids, [])
+ self.assertEqual(args, (1,))
+ self.assertEqual(kwargs, {})
+
+ xml = E.function(
+ E.value(eval="1"), E.value(name="context", eval="{'foo': 2}"),
+ model="test_convert.usered",
+ name="method",
+ )
+ rec, args, kwargs = self.eval_xml(xml, obj)
+ self.assertEqual(rec.env.context, {'foo': 2})
+ self.assertEqual(rec.ids, [1])
+ self.assertEqual(args, ())
+ self.assertEqual(kwargs, {})
+
+ def test_function_function(self):
+ obj = xml_import(self.cr, 'test_convert', None, 'init')
+
+ xml = E.function(
+ E.function(model="test_convert.usered", name="search", eval="[[]]"),
+ model="test_convert.usered",
+ name="method",
+ )
+ rec, args, kwargs = self.eval_xml(xml, obj)
+ self.assertEqual(rec.env.context, {})
+ self.assertEqual(rec.ids, [])
+ self.assertEqual(args, ())
+ self.assertEqual(kwargs, {})
+
@unittest.skip("not tested")
def test_xml(self):
pass
diff --git a/odoo/import_xml.rng b/odoo/import_xml.rng
index 953cac69e42..83324f379a9 100644
--- a/odoo/import_xml.rng
+++ b/odoo/import_xml.rng
@@ -23,6 +23,7 @@
<rng:define name="value">
<rng:element name="value">
+ <rng:optional><rng:attribute name="name" /></rng:optional>
<rng:optional><rng:attribute name="model" /></rng:optional>
<rng:choice>
<rng:attribute name="search" />
diff --git a/odoo/tools/convert.py b/odoo/tools/convert.py
index e677560979e..7a3ff444cce 100644
--- a/odoo/tools/convert.py
+++ b/odoo/tools/convert.py
@@ -177,32 +177,24 @@ def _eval_xml(self, node, env):
return tuple(res)
return res
elif node.tag == "function":
+ model = env[node.get('model')]
+ method_name = node.get('name')
+ # determine arguments
+ args = []
+ kwargs = {}
a_eval = node.get('eval')
if a_eval:
self.idref['ref'] = self.id_get
- # ensure the args are a list (sometimes folks eval a tuple which
- # is inconvenient when trying to concatenate w/ a list)
args = list(safe_eval(a_eval, self.idref))
- else:
- args = [
- r for r in (_eval_xml(self, n, env) for n in node)
- if r is not None
- ]
-
- model = env[node.get('model')]
- method_name = node.get('name')
- method = getattr(model, method_name)
-
- # this mess is necessary to merge @context and a possible positional
- # context parameter, as <function> works on the old API so ids and
- # context are just args
- ids, args = [], list(args)
- if getattr(method, '_api', None) not in ('model', 'model_create'):
- ids, args = args[:1], args[1:]
- context, args, kwargs = api.split_context(method, args, {})
- kwargs['context'] = {**env.context, **(context or {})}
-
- return odoo.api.call_kw(model, method_name, ids + args, kwargs)
+ for child in node:
+ if child.tag == 'value' and child.get('name'):
+ kwargs[child.get('name')] = _eval_xml(self, child, env)
+ else:
+ args.append(_eval_xml(self, child, env))
+ # merge current context with context in kwargs
+ kwargs['context'] = {**env.context, **kwargs.get('context', {})}
+ # invoke method
+ return odoo.api.call_kw(model, method_name, args, kwargs)
elif node.tag == "test":
return node.text