[FIX] routing_map: correct subclasses detection.
authorChristophe Simonis <chs@odoo.com>
Tue, 3 Jun 2014 15:48:08 +0000 (17:48 +0200)
committerChristophe Simonis <chs@odoo.com>
Tue, 3 Jun 2014 15:55:34 +0000 (17:55 +0200)
Subclass detection didn't include the class itself if all it's subclasses
were invalid. As we create a new regrouping subclass, that was always the
case after a registry reloading, causing subclassed controllers to not be
taken in account.

[IMP] routing_map: clean code a little bit

openerp/http.py

index 51d9499..abee8ac 100644 (file)
@@ -666,13 +666,17 @@ class EndPoint(object):
 def routing_map(modules, nodb_only, converters=None):
     routing_map = werkzeug.routing.Map(strict_slashes=False, converters=converters)
 
-    def get_subclasses(k):
+    def get_subclasses(klass):
         def valid(c):
             return c.__module__.startswith('openerp.addons.') and c.__module__.split(".")[2] in modules
-        s = k.__subclasses__()
-        if not s:
-            return [k] if valid(k) else []
-        return [u for t in s if valid(t) for u in get_subclasses(t)]
+        subclasses = klass.__subclasses__()
+        result = []
+        for subclass in subclasses:
+            if valid(subclass):
+                result.extend(get_subclasses(subclass))
+        if not result and valid(klass):
+            result = [klass]
+        return result
 
     uniq = lambda it: collections.OrderedDict((id(x), x) for x in it).values()
 
@@ -687,22 +691,23 @@ def routing_map(modules, nodb_only, converters=None):
                 cls = type(name, tuple(reversed(subclasses)), {})
 
             o = cls()
-            members = inspect.getmembers(o)
-            for mk, mv in members:
-                if inspect.ismethod(mv) and hasattr(mv, 'routing'):
+            members = inspect.getmembers(o, inspect.ismethod)
+            for _, mv in members:
+                if hasattr(mv, 'routing'):
                     routing = dict(type='http', auth='user', methods=None, routes=None)
                     methods_done = list()
+                    # update routing attributes from subclasses(auth, methods...)
                     for claz in reversed(mv.im_class.mro()):
                         fn = getattr(claz, mv.func_name, None)
                         if fn and hasattr(fn, 'routing') and fn not in methods_done:
                             methods_done.append(fn)
                             routing.update(fn.routing)
-                    if not nodb_only or nodb_only == (routing['auth'] == "none"):
+                    if not nodb_only or routing['auth'] == "none":
                         assert routing['routes'], "Method %r has not route defined" % mv
                         endpoint = EndPoint(mv, routing)
                         for url in routing['routes']:
                             if routing.get("combine", False):
-                                # deprecated
+                                # deprecated v7 declaration
                                 url = o._cp_path.rstrip('/') + '/' + url.lstrip('/')
                                 if url.endswith("/") and len(url) > 1:
                                     url = url[: -1]