diff options
| -rw-r--r-- | CHANGES.txt | 12 | ||||
| -rw-r--r-- | repoze/bfg/request.py | 12 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_request.py | 4 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_traversal.py | 20 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_urldispatch.py | 48 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_wsgi.py | 14 | ||||
| -rw-r--r-- | repoze/bfg/traversal.py | 7 | ||||
| -rw-r--r-- | repoze/bfg/urldispatch.py | 15 | ||||
| -rw-r--r-- | repoze/bfg/wsgi.py | 41 |
9 files changed, 48 insertions, 125 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index fe210bc34..e5cb81aa9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -160,6 +160,11 @@ Backwards Incompatibilities (and sending a new request event) within the router (it used to be performed afterwards). +- Adding ``*path_info`` to a route no longer changes the PATH_INFO for + a request that matches using URL dispatch. This feature was only + there to service the ``repoze.bfg.wsgi.wsgiapp2`` decorator and it + did it wrong; use ``*subpath`` instead now. + Bug Fixes --------- @@ -193,13 +198,6 @@ Documentation - Updated Routes bfgwiki2 tutorial to reflect the fact that context factories are now no longer used. -Internal --------- - -- Make Routes mapper responsible for doing magic to fix up PATH_INFO - and SCRIPT_NAME when a ``path_info`` key exists in the matchdict. - This used to be done in the traverser, which made no sense. - 0.9.1 (2009-06-02) ================== diff --git a/repoze/bfg/request.py b/repoze/bfg/request.py index 8a07c6b75..20e8070fc 100644 --- a/repoze/bfg/request.py +++ b/repoze/bfg/request.py @@ -56,11 +56,13 @@ def named_request_factories(name=None): else: IC = InterfaceClass default_iface = IC('%s_IRequest' % name, (IRequest,)) - get_iface = IC('%s_IGETRequest' % name, (IGETRequest,)) - post_iface = IC('%s_IPOSTRequest' % name, (IPOSTRequest,)) - put_iface = IC('%s_IPUTRequest' % name, (IPUTRequest,)) - delete_iface = IC('%s_IDELETERequest' % name, (IDELETERequest,)) - head_iface = IC('%s_IHEADRequest' % name, (IHEADRequest,)) + get_iface = IC('%s_IGETRequest' % name, (default_iface, IGETRequest)) + post_iface = IC('%s_IPOSTRequest' % name, (default_iface, IPOSTRequest)) + put_iface = IC('%s_IPUTRequest' % name, (default_iface, IPUTRequest)) + delete_iface = IC('%s_IDELETERequest' % name, (default_iface, + IDELETERequest)) + head_iface = IC('%s_IHEADRequest' % name, (default_iface, + IHEADRequest,)) class Request(WebobRequest): implements(default_iface) diff --git a/repoze/bfg/tests/test_request.py b/repoze/bfg/tests/test_request.py index 6855018b8..d5823e7d7 100644 --- a/repoze/bfg/tests/test_request.py +++ b/repoze/bfg/tests/test_request.py @@ -207,12 +207,14 @@ class TestNamedRequestFactories(unittest.TestCase): self.assertEqual(factories[alias], factories[iface]) named_iface = factories[alias]['interface'] named_factory = factories[alias]['factory'] + default_iface = factories[None]['interface'] self.assertEqual(factories[alias]['interface'], iface) self.assertEqual(factories[iface]['interface'], iface) self.assertEqual(factories[alias]['factory'].charset, 'utf-8') self.failUnless(named_iface.implementedBy(named_factory)) self.failUnless(iface.implementedBy(named_factory)) self.failUnless(IRequest.implementedBy(named_factory)) + self.failUnless(default_iface.implementedBy(named_factory)) def test_it_named(self): factories = self._callFUT('name') @@ -236,9 +238,11 @@ class TestNamedRequestFactories(unittest.TestCase): self.assertEqual(factories[alias]['factory'].charset, 'utf-8') named_iface = factories[alias]['interface'] named_factory = factories[alias]['factory'] + default_iface = factories[None]['interface'] self.failUnless(named_iface.implementedBy(named_factory)) self.failUnless(iface.implementedBy(named_factory)) self.failUnless(IRequest.implementedBy(named_factory)) + self.failUnless(default_iface.implementedBy(named_factory)) class TestDefaultRequestFactories(unittest.TestCase): def test_it(self): diff --git a/repoze/bfg/tests/test_traversal.py b/repoze/bfg/tests/test_traversal.py index c81665ab1..a756c3c1a 100644 --- a/repoze/bfg/tests/test_traversal.py +++ b/repoze/bfg/tests/test_traversal.py @@ -86,7 +86,7 @@ class ModelGraphTraverserTests(unittest.TestCase): result = policy(environ) self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], []) + self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], []) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], []) @@ -97,7 +97,7 @@ class ModelGraphTraverserTests(unittest.TestCase): result = policy(environ) self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], ['bar']) + self.assertEqual(result['subpath'], ('bar',)) self.assertEqual(result['traversed'], []) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], []) @@ -109,7 +109,7 @@ class ModelGraphTraverserTests(unittest.TestCase): result = policy(environ) self.assertEqual(result['context'], root) self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], []) + self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], []) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], []) @@ -122,7 +122,7 @@ class ModelGraphTraverserTests(unittest.TestCase): result = policy(environ) self.assertEqual(result['context'], foo) self.assertEqual(result['view_name'], 'bar') - self.assertEqual(result['subpath'], []) + self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], [u'foo']) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], []) @@ -135,7 +135,7 @@ class ModelGraphTraverserTests(unittest.TestCase): result = policy(environ) self.assertEqual(result['context'], foo) self.assertEqual(result['view_name'], 'bar') - self.assertEqual(result['subpath'], ['baz', 'buz']) + self.assertEqual(result['subpath'], ('baz', 'buz')) self.assertEqual(result['traversed'], [u'foo']) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], []) @@ -148,7 +148,7 @@ class ModelGraphTraverserTests(unittest.TestCase): result = policy(environ) self.assertEqual(result['context'], root) self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], []) + self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], []) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], []) @@ -168,7 +168,7 @@ class ModelGraphTraverserTests(unittest.TestCase): result = policy(environ) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], []) + self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], [u'foo', u'bar', u'baz']) self.assertEqual(result['virtual_root'], bar) self.assertEqual(result['virtual_root_path'], [u'foo', u'bar']) @@ -197,7 +197,7 @@ class ModelGraphTraverserTests(unittest.TestCase): result = traverser(environ) self.assertEqual(result['context'], model) self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], []) + self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], []) self.assertEqual(result['virtual_root'], model) self.assertEqual(result['virtual_root_path'], []) @@ -209,7 +209,7 @@ class ModelGraphTraverserTests(unittest.TestCase): result = traverser(environ) self.assertEqual(result['context'], model) self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ['a', 'b','c']) + self.assertEqual(result['subpath'], ('a', 'b','c')) self.assertEqual(result['traversed'], []) self.assertEqual(result['virtual_root'], model) self.assertEqual(result['virtual_root_path'], []) @@ -221,7 +221,7 @@ class ModelGraphTraverserTests(unittest.TestCase): result = traverser(environ) self.assertEqual(result['context'], model) self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], ['bar']) + self.assertEqual(result['subpath'], ('bar',)) self.assertEqual(result['traversed'], []) self.assertEqual(result['virtual_root'], model) self.assertEqual(result['virtual_root_path'], []) diff --git a/repoze/bfg/tests/test_urldispatch.py b/repoze/bfg/tests/test_urldispatch.py index eb3be4323..68fda032d 100644 --- a/repoze/bfg/tests/test_urldispatch.py +++ b/repoze/bfg/tests/test_urldispatch.py @@ -70,54 +70,6 @@ class RoutesRootFactoryTests(unittest.TestCase): self.assertEqual(environ['bfg.routes.matchdict'], {}) self.assertEqual(environ['wsgiorg.routing_args'], ((), {})) - def test_matches_with_path_info_no_scriptname(self): - root_factory = make_get_root(123) - mapper = self._makeOne(root_factory) - mapper.connect('root', '/a/b/*path_info') - environ = self._getEnviron(PATH_INFO='/a/b/c/d') - result = mapper(environ) - self.assertEqual(result, 123) - self.assertEqual(environ['bfg.routes.route'].name, 'root') - self.assertEqual(environ['bfg.routes.matchdict'], {'path_info':'c/d'}) - self.assertEqual(environ['PATH_INFO'], '/c/d') - self.assertEqual(environ['SCRIPT_NAME'], '/a/b') - - def test_matches_with_path_info_with_scriptname(self): - root_factory = make_get_root(123) - mapper = self._makeOne(root_factory) - mapper.connect('root', '/a/b/*path_info') - environ = self._getEnviron(PATH_INFO='/a/b/c/d', SCRIPT_NAME='z') - result = mapper(environ) - self.assertEqual(result, 123) - self.assertEqual(environ['bfg.routes.route'].name, 'root') - self.assertEqual(environ['bfg.routes.matchdict'], {'path_info':'c/d'}) - self.assertEqual(environ['PATH_INFO'], '/c/d') - self.assertEqual(environ['SCRIPT_NAME'], 'z/a/b') - - def test_matches_PATH_INFO_w_extra_slash(self): - root_factory = make_get_root(123) - mapper = self._makeOne(root_factory) - mapper.connect('root', '/a/b/*path_info') - environ = self._getEnviron(PATH_INFO='/a/b//c/d', SCRIPT_NAME='') - result = mapper(environ) - self.assertEqual(result, 123) - self.assertEqual(environ['bfg.routes.route'].name, 'root') - self.assertEqual(environ['bfg.routes.matchdict'], {'path_info':'/c/d'}) - self.assertEqual(environ['PATH_INFO'], '/c/d') - self.assertEqual(environ['SCRIPT_NAME'], '/a/b') - - def test_matches_SCRIPT_NAME_endswith_slash(self): - root_factory = make_get_root(123) - mapper = self._makeOne(root_factory) - mapper.connect('root', '/a/b//*path_info') - environ = self._getEnviron(PATH_INFO='/a/b//c/d', SCRIPT_NAME='') - result = mapper(environ) - self.assertEqual(result, 123) - self.assertEqual(environ['bfg.routes.route'].name, 'root') - self.assertEqual(environ['bfg.routes.matchdict'], {'path_info':'c/d'}) - self.assertEqual(environ['PATH_INFO'], '/c/d') - self.assertEqual(environ['SCRIPT_NAME'], '/a/b') - def test_unicode_in_route_default(self): root_factory = make_get_root(123) mapper = self._makeOne(root_factory) diff --git a/repoze/bfg/tests/test_wsgi.py b/repoze/bfg/tests/test_wsgi.py index 9d8a85630..5d3ec1faa 100644 --- a/repoze/bfg/tests/test_wsgi.py +++ b/repoze/bfg/tests/test_wsgi.py @@ -17,15 +17,7 @@ class WSGIApp2Tests(unittest.TestCase): from repoze.bfg.wsgi import wsgiapp2 return wsgiapp2(app) - def test_decorator_traversed_is_None(self): - context = DummyContext() - request = DummyRequest() - request.traversed = None - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - - def test_decorator_traversed_not_None_with_subpath_and_view_name(self): + def test_decorator_with_subpath_and_view_name(self): context = DummyContext() request = DummyRequest() request.traversed = ['a', 'b'] @@ -39,7 +31,7 @@ class WSGIApp2Tests(unittest.TestCase): self.assertEqual(request.environ['PATH_INFO'], '/subpath') self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/b/view_name') - def test_decorator_traversed_not_None_with_subpath_no_view_name(self): + def test_decorator_with_subpath_no_view_name(self): context = DummyContext() request = DummyRequest() request.traversed = ['a', 'b'] @@ -53,7 +45,7 @@ class WSGIApp2Tests(unittest.TestCase): self.assertEqual(request.environ['PATH_INFO'], '/subpath') self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/b') - def test_decorator_traversed_not_None_no_subpath_with_view_name(self): + def test_decorator_no_subpath_with_view_name(self): context = DummyContext() request = DummyRequest() request.traversed = ['a', 'b'] diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py index 576679853..16ab7c9f4 100644 --- a/repoze/bfg/traversal.py +++ b/repoze/bfg/traversal.py @@ -496,10 +496,11 @@ class ModelGraphTraverser(object): if 'bfg.routes.matchdict' in environ: matchdict = environ['bfg.routes.matchdict'] path = matchdict.get('traverse', '/') - subpath = filter(None, matchdict.get('subpath', '').split('/')) + subpath = matchdict.get('subpath', '') + subpath = tuple(filter(None, subpath.split('/'))) else: # this request did not match a Routes route - subpath = [] + subpath = () try: path = environ['PATH_INFO'] except KeyError: @@ -514,7 +515,7 @@ class ModelGraphTraverser(object): vroot_idx = len(vroot_path) path = vroot_path_string + path - path = list(traversal_path(path)) + path = traversal_path(path) traversed = [] diff --git a/repoze/bfg/urldispatch.py b/repoze/bfg/urldispatch.py index 591a91c57..6d12cae39 100644 --- a/repoze/bfg/urldispatch.py +++ b/repoze/bfg/urldispatch.py @@ -48,21 +48,6 @@ class RoutesRootFactory(Mapper): environ['bfg.routes.matchdict'] = args adhoc_attrs = environ.setdefault('webob.adhoc_attrs', {}) adhoc_attrs['matchdict'] = args - # this is stolen from routes.middleware; if the route map - # has a *path_info capture, use it to influence the path - # info and script_name of the generated environment - if 'path_info' in args: - if not 'SCRIPT_NAME' in environ: - environ['SCRIPT_NAME'] = '' - oldpath = environ['PATH_INFO'] - newpath = args['path_info'] or '' - environ['PATH_INFO'] = newpath - if not environ['PATH_INFO'].startswith('/'): - environ['PATH_INFO'] = '/' + environ['PATH_INFO'] - pattern = r'^(.*?)/' + re.escape(newpath) + '$' - environ['SCRIPT_NAME'] += re.sub(pattern, r'\1', oldpath) - if environ['SCRIPT_NAME'].endswith('/'): - environ['SCRIPT_NAME'] = environ['SCRIPT_NAME'][:-1] factory = route._factory or self.default_root_factory return factory(environ) diff --git a/repoze/bfg/wsgi.py b/repoze/bfg/wsgi.py index c7853c035..3991d3344 100644 --- a/repoze/bfg/wsgi.py +++ b/repoze/bfg/wsgi.py @@ -71,32 +71,21 @@ def wsgiapp2(wrapped): """ def decorator(context, request): traversed = request.traversed - if traversed is not None: - # We need to fix up PATH_INFO and SCRIPT_NAME to give the - # subapplication the right information, sans the info it - # took to traverse here. If ``traversed`` is None here, - # it means that no traversal was done. For example, it - # will be None in the case that the context is one - # obtained via a Routes match (Routes 'traversal' doesn't - # actually traverse). If this view is invoked on a Routes - # context, this fixup is not invoked. Instead, the route - # used to reach it should use *path_info in the actual - # route pattern to get a similar fix-up done. - vroot_path = request.virtual_root_path or [] - view_name = request.view_name - subpath = request.subpath or [] - script_list = traversed[len(vroot_path):] - script_list = [ quote_path_segment(name) for name in script_list ] - if view_name: - script_list.append(quote_path_segment(view_name)) - script_name = '/' + '/'.join(script_list) - path_list = [ quote_path_segment(name) for name in subpath ] - path_info = '/' + '/'.join(path_list) - request.environ['PATH_INFO'] = path_info - script_name = request.environ['SCRIPT_NAME'] + script_name - if script_name.endswith('/'): - script_name = script_name[:-1] - request.environ['SCRIPT_NAME'] = script_name + vroot_path = request.virtual_root_path or [] + view_name = request.view_name + subpath = request.subpath or () + script_list = traversed[len(vroot_path):] + script_list = [ quote_path_segment(name) for name in script_list ] + if view_name: + script_list.append(quote_path_segment(view_name)) + script_name = '/' + '/'.join(script_list) + path_list = [ quote_path_segment(name) for name in subpath ] + path_info = '/' + '/'.join(path_list) + request.environ['PATH_INFO'] = path_info + script_name = request.environ['SCRIPT_NAME'] + script_name + if script_name.endswith('/'): + script_name = script_name[:-1] + request.environ['SCRIPT_NAME'] = script_name return request.get_response(wrapped) return wraps(wrapped)(decorator) # grokkability |
