diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-06-22 02:30:13 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-06-22 02:30:13 +0000 |
| commit | 1cd5984995fefa64bdb7bdd47e6e09e8d424f6d2 (patch) | |
| tree | 5d111a0d62170b38320a9910c25306610a4987e2 | |
| parent | ffdbee31ce747c723988ef5ae94a0d02400718ba (diff) | |
| download | pyramid-1cd5984995fefa64bdb7bdd47e6e09e8d424f6d2.tar.gz pyramid-1cd5984995fefa64bdb7bdd47e6e09e8d424f6d2.tar.bz2 pyramid-1cd5984995fefa64bdb7bdd47e6e09e8d424f6d2.zip | |
- The values of ``subpath``, ``traversed``, and ``virtual_root_path``
attached to the request object are always now tuples instead of
lists (performance).
| -rw-r--r-- | CHANGES.txt | 4 | ||||
| -rw-r--r-- | repoze/bfg/testing.py | 9 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_testing.py | 5 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_traversal.py | 88 | ||||
| -rw-r--r-- | repoze/bfg/traversal.py | 46 | ||||
| -rw-r--r-- | repoze/bfg/wsgi.py | 6 |
6 files changed, 107 insertions, 51 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 9d3f35b3d..6528264e7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -165,6 +165,10 @@ Backwards Incompatibilities there to service the ``repoze.bfg.wsgi.wsgiapp2`` decorator and it did it wrong; use ``*subpath`` instead now. +- The values of ``subpath``, ``traversed``, and ``virtual_root_path`` + attached to the request object are always now tuples instead of + lists (performance). + Bug Fixes --------- diff --git a/repoze/bfg/testing.py b/repoze/bfg/testing.py index 19c462be4..52c383b65 100644 --- a/repoze/bfg/testing.py +++ b/repoze/bfg/testing.py @@ -383,11 +383,12 @@ class DummyRequest: self.path_qs = '' self.body = '' self.view_name = '' - self.subpath = [] - self.traversed = None - self.virtual_root = None - self.virtual_root_path = None + self.subpath = () + self.traversed = () + self.virtual_root_path = () self.context = None + self.root = None + self.virtual_root = None self.marshalled = params # repoze.monty self.__dict__.update(kw) diff --git a/repoze/bfg/tests/test_testing.py b/repoze/bfg/tests/test_testing.py index ff0846881..ca6f517be 100644 --- a/repoze/bfg/tests/test_testing.py +++ b/repoze/bfg/tests/test_testing.py @@ -349,8 +349,11 @@ class TestDummyRequest(unittest.TestCase): self.assertEqual(request.script_name, '') self.assertEqual(request.path_qs, '') self.assertEqual(request.view_name, '') - self.assertEqual(request.subpath, []) + self.assertEqual(request.subpath, ()) self.assertEqual(request.context, None) + self.assertEqual(request.root, None) + self.assertEqual(request.virtual_root, None) + self.assertEqual(request.virtual_root_path, ()) def test_params_explicit(self): request = self._makeOne(params = {'foo':'bar'}) diff --git a/repoze/bfg/tests/test_traversal.py b/repoze/bfg/tests/test_traversal.py index a756c3c1a..da52ab968 100644 --- a/repoze/bfg/tests/test_traversal.py +++ b/repoze/bfg/tests/test_traversal.py @@ -87,9 +87,9 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], []) + self.assertEqual(result['traversed'], ()) self.assertEqual(result['virtual_root'], policy.root) - self.assertEqual(result['virtual_root_path'], []) + self.assertEqual(result['virtual_root_path'], ()) def test_call_pathel_with_no_getitem(self): policy = self._makeOne(None) @@ -98,9 +98,9 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ('bar',)) - self.assertEqual(result['traversed'], []) + self.assertEqual(result['traversed'], ()) self.assertEqual(result['virtual_root'], policy.root) - self.assertEqual(result['virtual_root_path'], []) + self.assertEqual(result['virtual_root_path'], ()) def test_call_withconn_getitem_emptypath_nosubpath(self): root = DummyContext() @@ -110,9 +110,9 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['context'], root) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], []) + self.assertEqual(result['traversed'], ()) self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], []) + self.assertEqual(result['virtual_root_path'], ()) def test_call_withconn_getitem_withpath_nosubpath(self): foo = DummyContext() @@ -123,9 +123,9 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['context'], foo) self.assertEqual(result['view_name'], 'bar') self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], [u'foo']) + self.assertEqual(result['traversed'], (u'foo',)) self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], []) + self.assertEqual(result['virtual_root_path'], ()) def test_call_withconn_getitem_withpath_withsubpath(self): foo = DummyContext() @@ -136,9 +136,9 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['context'], foo) self.assertEqual(result['view_name'], 'bar') self.assertEqual(result['subpath'], ('baz', 'buz')) - self.assertEqual(result['traversed'], [u'foo']) + self.assertEqual(result['traversed'], (u'foo',)) self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], []) + self.assertEqual(result['virtual_root_path'], ()) def test_call_with_explicit_viewname(self): foo = DummyContext() @@ -149,29 +149,69 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['context'], root) self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], []) + self.assertEqual(result['traversed'], ()) self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], []) + self.assertEqual(result['virtual_root_path'], ()) def test_call_with_vh_root(self): environ = self._getEnviron(PATH_INFO='/baz', HTTP_X_VHM_ROOT='/foo/bar') baz = DummyContext() - baz.name = 'baz' bar = DummyContext(baz) - bar.name = 'bar' foo = DummyContext(bar) - foo.name = 'foo' root = DummyContext(foo) - root.name = 'root' policy = self._makeOne(root) result = policy(environ) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], [u'foo', u'bar', u'baz']) + 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']) + self.assertEqual(result['virtual_root_path'], (u'foo', u'bar')) + + def test_call_with_vh_root2(self): + environ = self._getEnviron(PATH_INFO='/bar/baz', + HTTP_X_VHM_ROOT='/foo') + baz = DummyContext() + bar = DummyContext(baz) + foo = DummyContext(bar) + root = DummyContext(foo) + policy = self._makeOne(root) + result = policy(environ) + self.assertEqual(result['context'], baz) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], (u'foo', u'bar', u'baz')) + self.assertEqual(result['virtual_root'], foo) + self.assertEqual(result['virtual_root_path'], (u'foo',)) + + def test_call_with_vh_root3(self): + environ = self._getEnviron(PATH_INFO='/foo/bar/baz', + HTTP_X_VHM_ROOT='/') + baz = DummyContext() + bar = DummyContext(baz) + foo = DummyContext(bar) + root = DummyContext(foo) + policy = self._makeOne(root) + result = policy(environ) + self.assertEqual(result['context'], baz) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], (u'foo', u'bar', u'baz')) + self.assertEqual(result['virtual_root'], root) + self.assertEqual(result['virtual_root_path'], ()) + + def test_call_with_vh_root_path_root(self): + policy = self._makeOne(None) + environ = self._getEnviron(HTTP_X_VHM_ROOT='/', + PATH_INFO='/') + result = policy(environ) + self.assertEqual(result['context'], None) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['virtual_root'], policy.root) + self.assertEqual(result['virtual_root_path'], ()) def test_non_utf8_path_segment_unicode_path_segments_fails(self): foo = DummyContext() @@ -198,9 +238,9 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['context'], model) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], []) + self.assertEqual(result['traversed'], ()) self.assertEqual(result['virtual_root'], model) - self.assertEqual(result['virtual_root_path'], []) + self.assertEqual(result['virtual_root_path'], ()) def test_withroute_with_subpath(self): model = DummyContext() @@ -210,9 +250,9 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['context'], model) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ('a', 'b','c')) - self.assertEqual(result['traversed'], []) + self.assertEqual(result['traversed'], ()) self.assertEqual(result['virtual_root'], model) - self.assertEqual(result['virtual_root_path'], []) + self.assertEqual(result['virtual_root_path'], ()) def test_withroute_and_traverse(self): model = DummyContext() @@ -222,9 +262,9 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['context'], model) self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ('bar',)) - self.assertEqual(result['traversed'], []) + self.assertEqual(result['traversed'], ()) self.assertEqual(result['virtual_root'], model) - self.assertEqual(result['virtual_root_path'], []) + self.assertEqual(result['virtual_root_path'], ()) class FindInterfaceTests(unittest.TestCase): def _callFUT(self, context, iface): diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py index 16ab7c9f4..428553ec6 100644 --- a/repoze/bfg/traversal.py +++ b/repoze/bfg/traversal.py @@ -505,52 +505,60 @@ class ModelGraphTraverser(object): path = environ['PATH_INFO'] except KeyError: path = '/' + try: vroot_path_string = environ[VH_ROOT_KEY] except KeyError: - vroot_path = [] + vroot_path = () vroot_idx = 0 else: - vroot_path = list(traversal_path(vroot_path_string)) + vroot_path = traversal_path(vroot_path_string) vroot_idx = len(vroot_path) path = vroot_path_string + path path = traversal_path(path) - - traversed = [] - ob = vroot = self.root - name = '' + + # in case you're wondering, we do dead reckoning here instead + # of pushing and popping temporary lists for speed purposes i = 1 + j = vroot_idx for segment in path: if segment[:2] =='@@': - return dict(context=ob, view_name=segment[2:], subpath=path[i:], - traversed=traversed, virtual_root=vroot, - virtual_root_path=vroot_path, root=self.root) + return dict(context=ob, view_name=segment[2:], + subpath=path[i:], traversed=path[:j], + virtual_root=vroot, + virtual_root_path=vroot_path, + root=self.root) try: getitem = ob.__getitem__ except AttributeError: - return dict(context=ob, view_name=segment, subpath=path[i:], - traversed=traversed, virtual_root=vroot, - virtual_root_path=vroot_path, root=self.root) + return dict(context=ob, view_name=segment, + subpath=path[i:], traversed=path[:j], + virtual_root=vroot, + virtual_root_path=vroot_path, + root=self.root) + try: next = getitem(segment) except KeyError: - return dict(context=ob, view_name=segment, subpath=path[i:], - traversed=traversed, virtual_root=vroot, - virtual_root_path=vroot_path, root=self.root) + return dict(context=ob, view_name=segment, + subpath=path[i:], traversed=path[:j], + virtual_root=vroot, + virtual_root_path=vroot_path, + root=self.root) + if vroot_idx == i-1: vroot = ob - traversed.append(segment) ob = next i += 1 + j += 1 return dict(context=ob, view_name=u'', subpath=subpath, - traversed=traversed, virtual_root=vroot, - virtual_root_path=vroot_path, - root=self.root) + traversed=path, virtual_root=vroot, + virtual_root_path=vroot_path, root=self.root) class TraversalContextURL(object): """ The IContextURL adapter used to generate URLs for a context diff --git a/repoze/bfg/wsgi.py b/repoze/bfg/wsgi.py index 3991d3344..545b3e93c 100644 --- a/repoze/bfg/wsgi.py +++ b/repoze/bfg/wsgi.py @@ -71,11 +71,11 @@ def wsgiapp2(wrapped): """ def decorator(context, request): traversed = request.traversed - vroot_path = request.virtual_root_path or [] + 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 ] + script_tuple = traversed[len(vroot_path):] + script_list = [ quote_path_segment(name) for name in script_tuple ] if view_name: script_list.append(quote_path_segment(view_name)) script_name = '/' + '/'.join(script_list) |
