[FIX] Extension of controller in-place with explicit spec of same _cp_path
authorXavier Morel <xmo@openerp.com>
Thu, 18 Apr 2013 09:24:05 +0000 (11:24 +0200)
committerXavier Morel <xmo@openerp.com>
Thu, 18 Apr 2013 09:24:05 +0000 (11:24 +0200)
When extending a controller in-place (e.g. A(Controller), B(A)) and
providing the exact same _cp_path as parent (no-op) execution path
would go into handler for _cp_path overwriting and raise an assertion
error for overwriting of existing controller.

Except this is allowed (if ugly) pattern, so warn & ignore behavior
(it is harmless).

bzr revid: xmo@openerp.com-20130418092405-wrmmrd648b9koefu

addons/web/http.py
addons/web/tests/test_dispatch.py

index f08d7c6..9439d7a 100644 (file)
@@ -381,6 +381,12 @@ class ControllerType(type):
 
             # inherit from a Controller subclass
             if path:
+                # if extending in place with same URL, ignore URL
+                if parent_path == path:
+                    _logger.warn(
+                        "Controller %s extending %s in-place should not "
+                        "explicitly specify URL", cls, parent)
+                    return
                 _logger.warn("Re-exposing %s at %s.\n"
                              "\tThis usage is unsupported.",
                              parent.__name__,
@@ -398,7 +404,7 @@ class Controller(object):
 
     def __new__(cls, *args, **kwargs):
         subclasses = [c for c in cls.__subclasses__()
-                      if c._cp_path is cls._cp_path]
+                      if c._cp_path == cls._cp_path]
         if subclasses:
             name = "%s (+%s)" % (
                 cls.__name__,
index b1304fc..b532ceb 100644 (file)
@@ -242,6 +242,29 @@ class TestSubclassing(DispatchCleanup):
         self.assertEqual('200 OK', status)
         self.assertEqual('1 2 3', ''.join(body))
 
+    def test_extends_same_path(self):
+        """
+        When subclassing an existing Controller and specifying the same
+        _cp_path as the parent, ???
+        """
+        class A(http.Controller):
+            _cp_path = '/foo'
+            @http.httprequest
+            def index(self, req):
+                return '1'
+
+        class B(A):
+            _cp_path = '/foo'
+            @http.httprequest
+            def index(self, req):
+                return '2'
+
+        self.app.load_addons()
+
+        body, status, headers = self.client.get('/foo')
+        self.assertEqual('200 OK', status)
+        self.assertEqual('2', ''.join(body))
+
     def test_re_expose(self):
         """
         An existing Controller should not be extended with a new cp_path