[FIX] *: ormcache works with annotation

The `ormcache` decorator fails to create the key method
(`determine_key`) when the method signature contains any annotation.
Fix it by removing annotation of the signature.

closes odoo/odoo#109777

Signed-off-by: Raphael Collet <rco@odoo.com>
This commit is contained in:
Rémy Voet (ryv)
2023-01-23 14:25:14 +01:00
parent 0b335ad510
commit f6cf94d4bd
2 changed files with 17 additions and 5 deletions
+1 -1
View File
@@ -1999,7 +1999,7 @@ class IrModelData(models.Model):
# NEW V8 API
@api.model
@tools.ormcache('xmlid')
def _xmlid_lookup(self, xmlid):
def _xmlid_lookup(self, xmlid: str) -> tuple:
"""Low level xmlid lookup
Return (id, res_model, res_id) or raise ValueError if not found
"""
+16 -4
View File
@@ -4,7 +4,7 @@
# decorator makes wrappers that have the same API as their wrapped function
from collections import Counter, defaultdict
from decorator import decorator
from inspect import signature
from inspect import signature, Parameter
import logging
unsafe_eval = eval
@@ -64,7 +64,13 @@ class ormcache(object):
""" Determine the function that computes a cache key from arguments. """
if self.skiparg is None:
# build a string that represents function code and evaluate it
args = str(signature(self.method))[1:-1]
args = ', '.join(
# remove annotations because lambdas can't be type-annotated,
# and defaults because they are redundant (defaults are present
# in the wrapper function itself)
str(params.replace(annotation=Parameter.empty, default=Parameter.empty))
for params in signature(self.method).parameters.values()
)
if self.args:
code = "lambda %s: (%s,)" % (args, ", ".join(self.args))
else:
@@ -114,7 +120,10 @@ class ormcache_context(ormcache):
assert self.skiparg is None, "ormcache_context() no longer supports skiparg"
# build a string that represents function code and evaluate it
sign = signature(self.method)
args = str(sign)[1:-1]
args = ', '.join(
str(params.replace(annotation=Parameter.empty, default=Parameter.empty))
for params in sign.parameters.values()
)
cont_expr = "(context or {})" if 'context' in sign.parameters else "self._context"
keys_expr = "tuple(%s.get(k) for k in %r)" % (cont_expr, self.keys)
if self.args:
@@ -143,7 +152,10 @@ class ormcache_multi(ormcache):
# key_multi computes the extra element added to the key
sign = signature(self.method)
args = str(sign)[1:-1]
args = ', '.join(
str(params.replace(annotation=Parameter.empty, default=Parameter.empty))
for params in sign.parameters.values()
)
code_multi = "lambda %s: %s" % (args, self.multi)
self.key_multi = unsafe_eval(code_multi)