Skip to content

Commit

Permalink
[FIX] base: enforce the usage of ir.qweb instead of qweb
Browse files Browse the repository at this point in the history
Purpose
=======
Clarify that qweb should be used as <ir.qweb> when the latter is
available. <ir.qweb> version is a an optimized version of QWeb rendering
and using it is better for performance and daily usage. Moreover it used
Odoo model instead of standard python class, that's why we do not want
people to use QWeb instead of <ir.qweb>.

Task-2709589

closes odoo#82724

X-original-commit: fae39c9
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
  • Loading branch information
std-odoo committed Jan 14, 2022
1 parent 2296746 commit 8ec7739
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 16 deletions.
11 changes: 10 additions & 1 deletion odoo/addons/base/models/ir_qweb.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
from __future__ import print_function
from textwrap import dedent
import copy
import io
import logging
import re
import markupsafe
import tokenize
from lxml import html, etree

from odoo import api, models, tools
Expand Down Expand Up @@ -376,6 +378,13 @@ def _compile_expr(self, expr, raise_on_missing=False):
:param expr: string
"""
namespace_expr = super()._compile_expr(expr, raise_on_missing=raise_on_missing)
readable = io.BytesIO(expr.strip().encode('utf-8'))
try:
tokens = list(tokenize.tokenize(readable.readline))
except tokenize.TokenError:
raise ValueError(f"Cannot compile expression: {expr}")

namespace_expr = self._compile_expr_tokens(tokens, self._allowed_keyword + list(self._available_objects.keys()), raise_on_missing=raise_on_missing)

assert_valid_codeobj(_SAFE_QWEB_OPCODES, compile(namespace_expr, '<>', 'eval'), expr)
return namespace_expr
16 changes: 2 additions & 14 deletions odoo/addons/base/models/qweb.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,20 +574,8 @@ def _compile_expr_tokens(self, tokens, allowed_keys, argument_names=None, raise_
return ''.join(code)

def _compile_expr(self, expr, raise_on_missing=False):
"""Transform string coming into a python instruction in textual form by
adding the namepaces for the dynamic values.
This method tokenize the string and call ``_compile_expr_tokens``
method.
"""
readable = io.BytesIO(expr.strip().encode('utf-8'))
try:
tokens = list(tokenize.tokenize(readable.readline))
except tokenize.TokenError:
raise ValueError(f"Can not compile expression: {expr}")

expression = self._compile_expr_tokens(tokens, self._allowed_keyword + list(self._available_objects.keys()), raise_on_missing=raise_on_missing)

return f"({expression})"
"""This method must be overridden by <ir.qweb> in order to compile the template."""
raise NotImplementedError("Templates should use the ir.qweb compile method")

def _compile_bool(self, attr, default=False):
"""Convert the statements as a boolean."""
Expand Down
2 changes: 1 addition & 1 deletion odoo/addons/base/tests/test_qweb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1110,7 +1110,7 @@ def test_error_message_2(self):
try:
self.env['ir.qweb']._render(t.id)
except QWebException as e:
self.assertIn('Can not compile expression', e.message)
self.assertIn('Cannot compile expression', e.message)
self.assertIn('<div t-esc="abc + def + ("/>', e.message)

from copy import deepcopy
Expand Down

0 comments on commit 8ec7739

Please sign in to comment.