summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt12
-rw-r--r--repoze/bfg/request.py12
-rw-r--r--repoze/bfg/tests/test_request.py4
-rw-r--r--repoze/bfg/tests/test_traversal.py20
-rw-r--r--repoze/bfg/tests/test_urldispatch.py48
-rw-r--r--repoze/bfg/tests/test_wsgi.py14
-rw-r--r--repoze/bfg/traversal.py7
-rw-r--r--repoze/bfg/urldispatch.py15
-rw-r--r--repoze/bfg/wsgi.py41
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