summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-06-22 02:30:13 +0000
committerChris McDonough <chrism@agendaless.com>2009-06-22 02:30:13 +0000
commit1cd5984995fefa64bdb7bdd47e6e09e8d424f6d2 (patch)
tree5d111a0d62170b38320a9910c25306610a4987e2
parentffdbee31ce747c723988ef5ae94a0d02400718ba (diff)
downloadpyramid-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.txt4
-rw-r--r--repoze/bfg/testing.py9
-rw-r--r--repoze/bfg/tests/test_testing.py5
-rw-r--r--repoze/bfg/tests/test_traversal.py88
-rw-r--r--repoze/bfg/traversal.py46
-rw-r--r--repoze/bfg/wsgi.py6
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)