[FIX] core: skip useless controllers in routingmap

The routing-map is a mapping that maps HTTP verbs and paths to python
controller methods (endpoints), e.g. it maps `GET /web/health/` to
`/web:Home.health`. The `_generate_routing_map` function is the function
responsible to generating the werkzeug routing-map in regard to the
controller inheritance mechanism. The mechanism makes it possible to
override an endpoint is various odoo modules to enrich it with new
features, e.g. `/web/login` is overriden in website to change the visual
of the page.

Implementation-wise, the informations from each `@route` decorator must
be merged with the other `@route` info for each endpoint override. When
a method is not overriden in a controller, there is not new info and
that controller should be skipped for that method.

The previous implementation attempted to skip such method using the
following idiom:

    if not hasattr(controller, method_name):
        continue

That idiom doesn't work as `hasattr` will perform a lookup on the full
controller's MRO instead of a lookup only on controller's own methods
and attributes. The controller's own methods and attributes are
actually found in `controller.__dict__`.

closes odoo/odoo#107064

X-original-commit: 42f52d26b6a81a68f1fe28e28971f0e7f4c97d11
Signed-off-by: Julien Castiaux <juc@odoo.com>
This commit is contained in:
Julien Castiaux
2022-12-05 16:06:49 +01:00
parent d151158637
commit 05a3ad3159
+3 -3
View File
@@ -779,10 +779,10 @@ def _generate_routing_rules(modules, nodb_only, converters=None):
'readonly': False,
}
for cls in unique(reversed(type(ctrl).mro())): # ancestors first
submethod = getattr(cls, method_name, None)
if submethod is None:
for cls in unique(reversed(type(ctrl).mro()[:-2])): # ancestors first
if method_name not in cls.__dict__:
continue
submethod = getattr(cls, method_name)
if not hasattr(submethod, 'original_routing'):
_logger.warning("The endpoint %s is not decorated by @route(), decorating it myself.", f'{cls.__module__}.{cls.__name__}.{method_name}')