From 05a3ad315914289bdbe9919992318ab8c99853af Mon Sep 17 00:00:00 2001 From: Julien Castiaux Date: Mon, 28 Nov 2022 16:44:22 +0000 Subject: [PATCH] [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 --- odoo/http.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/odoo/http.py b/odoo/http.py index 20f286136c8..4d5ba9a712e 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -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}')