From 8cfe7068783a3520aa3bc09f260502d002e9ac60 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 25 Jan 2009 20:52:35 +0000 Subject: - The ``repoze.bfg.urldispatch.RoutesRootFactory`` now injects the ``wsgiorg.routing_args`` environment variable into the environ when a route matches. This is a tuple of ((), routing_args) where routing_args is the value that comes back from the routes mapper match (the "match dict"). - The ``repoze.bfg.traversal.RoutesModelTraverser`` class now wants to obtain the ``view_name`` and ``subpath`` from the ``wsgiorgs.routing_args`` environment variable. It falls back to obtaining these from the context for backwards compatibility. --- CHANGES.txt | 12 ++++++++++++ repoze/bfg/tests/test_traversal.py | 28 ++++++++++++++++++++++++---- repoze/bfg/tests/test_urldispatch.py | 6 ++++++ repoze/bfg/traversal.py | 29 ++++++++++++++++++++++++----- repoze/bfg/urldispatch.py | 1 + 5 files changed, 67 insertions(+), 9 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 524ccf508..2f996a932 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ Next Release +============ Features -------- @@ -39,6 +40,17 @@ Behavior Changes feature was never documented, and was never an API, so it's not a backwards incompatibility. +- The ``repoze.bfg.urldispatch.RoutesRootFactory`` now injects the + ``wsgiorg.routing_args`` environment variable into the environ when + a route matches. This is a tuple of ((), routing_args) where + routing_args is the value that comes back from the routes mapper + match (the "match dict"). + +- The ``repoze.bfg.traversal.RoutesModelTraverser`` class now wants to + obtain the ``view_name`` and ``subpath`` from the + ``wsgiorgs.routing_args`` environment variable. It falls back to + obtaining these from the context for backwards compatibility. + Implementation Changes ---------------------- diff --git a/repoze/bfg/tests/test_traversal.py b/repoze/bfg/tests/test_traversal.py index 2de08a314..04dfd1bca 100644 --- a/repoze/bfg/tests/test_traversal.py +++ b/repoze/bfg/tests/test_traversal.py @@ -225,7 +225,7 @@ class RoutesModelTraverserTests(unittest.TestCase): from repoze.bfg.interfaces import ITraverser verifyObject(ITraverser, self._makeOne(None)) - def test_call_with_only_controller(self): + def test_call_with_only_controller_bwcompat(self): model = DummyContext() model.controller = 'controller' traverser = self._makeOne(model) @@ -234,7 +234,7 @@ class RoutesModelTraverserTests(unittest.TestCase): self.assertEqual(result[1], 'controller') self.assertEqual(result[2], []) - def test_call_with_only_view_name(self): + def test_call_with_only_view_name_bwcompat(self): model = DummyContext() model.view_name = 'view_name' traverser = self._makeOne(model) @@ -243,7 +243,7 @@ class RoutesModelTraverserTests(unittest.TestCase): self.assertEqual(result[1], 'view_name') self.assertEqual(result[2], []) - def test_call_with_subpath(self): + def test_call_with_subpath_bwcompat(self): model = DummyContext() model.view_name = 'view_name' model.subpath = '/a/b/c' @@ -253,7 +253,7 @@ class RoutesModelTraverserTests(unittest.TestCase): self.assertEqual(result[1], 'view_name') self.assertEqual(result[2], ['a', 'b', 'c']) - def test_call_with_no_view_name_or_controller(self): + def test_call_with_no_view_name_or_controller_bwcompat(self): model = DummyContext() traverser = self._makeOne(model) result = traverser({}) @@ -261,6 +261,26 @@ class RoutesModelTraverserTests(unittest.TestCase): self.assertEqual(result[1], '') self.assertEqual(result[2], []) + def test_call_with_only_view_name(self): + model = DummyContext() + traverser = self._makeOne(model) + routing_args = ((), {'view_name':'view_name'}) + environ = {'wsgiorg.routing_args': routing_args} + result = traverser(environ) + self.assertEqual(result[0], model) + self.assertEqual(result[1], 'view_name') + self.assertEqual(result[2], []) + + def test_call_with_view_name_and_subpath(self): + model = DummyContext() + traverser = self._makeOne(model) + routing_args = ((), {'view_name':'view_name', 'subpath':'/a/b/c'}) + environ = {'wsgiorg.routing_args': routing_args} + result = traverser(environ) + self.assertEqual(result[0], model) + self.assertEqual(result[1], 'view_name') + self.assertEqual(result[2], ['a', 'b','c']) + class FindInterfaceTests(unittest.TestCase): def _callFUT(self, context, iface): from repoze.bfg.traversal import find_interface diff --git a/repoze/bfg/tests/test_urldispatch.py b/repoze/bfg/tests/test_urldispatch.py index e332351a7..71ac78698 100644 --- a/repoze/bfg/tests/test_urldispatch.py +++ b/repoze/bfg/tests/test_urldispatch.py @@ -111,6 +111,10 @@ class RoutesRootFactoryTests(unittest.TestCase): self.assertEqual(result.view_name, 'foo') self.assertEqual(result.action, 'action1') self.assertEqual(result.article, 'article1') + routing_args = environ['wsgiorg.routing_args'][1] + self.assertEqual(routing_args['view_name'], 'foo') + self.assertEqual(routing_args['action'], 'action1') + self.assertEqual(routing_args['article'], 'article1') def test_unicode_in_route_default(self): marker = () @@ -128,6 +132,8 @@ class RoutesRootFactoryTests(unittest.TestCase): from repoze.bfg.interfaces import IRoutesContext self.failUnless(IRoutesContext.providedBy(result)) self.assertEqual(getattr(result, la.encode('utf-8')), 'id') + routing_args = environ['wsgiorg.routing_args'][1] + self.assertEqual(routing_args[la.encode('utf-8')], 'id') def test_no_fallback_get_root(self): marker = () diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py index d3befe86c..2d56f9302 100644 --- a/repoze/bfg/traversal.py +++ b/repoze/bfg/traversal.py @@ -172,9 +172,28 @@ class RoutesModelTraverser(object): self.context = context def __call__(self, environ): - view_name = getattr(self.context, 'controller', None) # b/w compat<0.6.3 - if view_name is None: - view_name = getattr(self.context, 'view_name', '') # 0.6.3+ - subpath = getattr(self.context, 'subpath', '') # 0.6.3+ - subpath = filter(None, subpath.split('/')) + # the traverser *wants* to get routing args from the environ + # as of 0.6.5; the rest of this stuff is for backwards + # compatibility + try: + # 0.6.5 + + routing_args = environ['wsgiorg.routing_args'][1] + except KeyError: + # <= 0.6.4 + routing_args = self.context.__dict__ + try: + view_name = routing_args['view_name'] + except KeyError: + # b/w compat < 0.6.3 + try: + view_name = routing_args['controller'] + except KeyError: + view_name = '' + try: + subpath = routing_args['subpath'] + subpath = filter(None, subpath.split('/')) + except KeyError: + # b/w compat < 0.6.5 + subpath = [] + return self.context, view_name, subpath diff --git a/repoze/bfg/urldispatch.py b/repoze/bfg/urldispatch.py index f1470cd25..0c71c6e74 100644 --- a/repoze/bfg/urldispatch.py +++ b/repoze/bfg/urldispatch.py @@ -177,6 +177,7 @@ class RoutesRootFactory(Mapper): k = k.encode('utf-8') kw[k] = v context = factory(**kw) + environ['wsgiorg.routing_args'] = ((), kw) provides = route._provides for iface in provides: alsoProvides(context, iface) -- cgit v1.2.3