summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-08-08 02:39:40 -0400
committerChris McDonough <chrism@plope.com>2011-08-08 02:39:40 -0400
commitfd78f1b38496e2eda00e6efa08a52fdb7d922b99 (patch)
treefbc4819e28ae2943e20378ab99c4d5175a56e5c9
parent06b15bf2024b553556ab8a56c185ec7229d20ed8 (diff)
downloadpyramid-fd78f1b38496e2eda00e6efa08a52fdb7d922b99.tar.gz
pyramid-fd78f1b38496e2eda00e6efa08a52fdb7d922b99.tar.bz2
pyramid-fd78f1b38496e2eda00e6efa08a52fdb7d922b99.zip
add tween aliases
-rw-r--r--pyramid/config.py36
-rw-r--r--pyramid/paster.py52
-rw-r--r--pyramid/tests/test_paster.py34
-rw-r--r--pyramid/tests/test_tweens.py101
-rw-r--r--pyramid/tweens.py89
5 files changed, 191 insertions, 121 deletions
diff --git a/pyramid/config.py b/pyramid/config.py
index 6ae9a70ce..d947376c8 100644
--- a/pyramid/config.py
+++ b/pyramid/config.py
@@ -905,7 +905,7 @@ class Configurator(object):
return self._derive_view(view, attr=attr, renderer=renderer)
@action_method
- def add_tween(self, tween_factory, below=None, atop=None):
+ def add_tween(self, tween_factory, alias=None, below=None, atop=None):
"""
Add a 'tween factory'. A :term:`tween` (think: 'between') is a bit
of code that sits between the Pyramid router's main request handling
@@ -922,25 +922,27 @@ class Configurator(object):
.. note:: This feature is new as of Pyramid 1.1.1.
"""
- return self._add_tween(tween_factory, below=below, atop=atop,
- explicit=False)
+ return self._add_tween(tween_factory, alias=alias, below=below,
+ atop=atop, explicit=False)
- def _add_tween(self, tween_factory, below=None, atop=None, explicit=False):
+ def _add_tween(self, tween_factory, alias=None, below=None, atop=None,
+ explicit=False):
tween_factory = self.maybe_dotted(tween_factory)
name = tween_factory_name(tween_factory)
- def register():
- registry = self.registry
- tweens = registry.queryUtility(ITweens)
- if tweens is None:
- tweens = Tweens()
- registry.registerUtility(tweens, ITweens)
- tweens.add_implicit(tween_factory_name(excview_tween_factory),
- excview_tween_factory, below=MAIN)
- if explicit:
- tweens.add_explicit(name, tween_factory)
- else:
- tweens.add_implicit(name, tween_factory, below=below, atop=atop)
- self.action(('tween', name, explicit), register)
+ registry = self.registry
+ tweens = registry.queryUtility(ITweens)
+ if tweens is None:
+ tweens = Tweens()
+ registry.registerUtility(tweens, ITweens)
+ tweens.add_implicit(tween_factory_name(excview_tween_factory),
+ excview_tween_factory, alias='excview',
+ below=MAIN)
+ if explicit:
+ tweens.add_explicit(name, tween_factory)
+ else:
+ tweens.add_implicit(name, tween_factory, alias=alias,
+ below=below, atop=atop)
+ self.action(('tween', name, explicit))
@action_method
def add_request_handler(self, factory, name): # pragma: no cover
diff --git a/pyramid/paster.py b/pyramid/paster.py
index e7ec8fb93..46d45f801 100644
--- a/pyramid/paster.py
+++ b/pyramid/paster.py
@@ -14,6 +14,9 @@ from pyramid.interfaces import ITweens
from pyramid.scripting import prepare
from pyramid.util import DottedNameResolver
+from pyramid.tweens import MAIN
+from pyramid.tweens import INGRESS
+
from pyramid.scaffolds import PyramidTemplate # bw compat
zope.deprecation.deprecated(
'PyramidTemplate', ('pyramid.paster.PyramidTemplate was moved to '
@@ -567,6 +570,28 @@ class PTweensCommand(PCommand):
def out(self, msg): # pragma: no cover
print msg
+
+ def show_implicit(self, tweens):
+ implicit = tweens.implicit()
+ fmt = '%-10s %-50s %-15s'
+ self.out(fmt % ('Position', 'Name', 'Alias'))
+ self.out(fmt % (
+ '-'*len('Position'), '-'*len('Name'), '-'*len('Alias')))
+ self.out(fmt % ('-', '-', MAIN))
+ for pos, (name, _) in enumerate(implicit):
+ alias = tweens.name_to_alias.get(name, None)
+ self.out(fmt % (pos, name, alias))
+ self.out(fmt % ('-', '-', INGRESS))
+
+ def show_explicit(self, tweens):
+ explicit = tweens.explicit
+ fmt = '%-10s %-65s'
+ self.out(fmt % ('Position', 'Name'))
+ self.out(fmt % ('-'*len('Position'), '-'*len('Name')))
+ self.out(fmt % ('-', MAIN))
+ for pos, (name, _) in enumerate(explicit):
+ self.out(fmt % (pos, name))
+ self.out(fmt % ('-', INGRESS))
def command(self):
config_uri = self.args[0]
@@ -574,31 +599,22 @@ class PTweensCommand(PCommand):
registry = env['registry']
tweens = self._get_tweens(registry)
if tweens is not None:
- implicit = tweens.implicit()
explicit = tweens.explicit
- ordering = []
if explicit:
self.out('"pyramid.tweens" config value set '
'(explicitly ordered tweens used)')
self.out('')
- ordering.append((explicit,
- 'Explicit Tween Chain (used)'))
- ordering.append((implicit,
- 'Implicit Tween Chain (not used)'))
+ self.out('Explicit Tween Chain (used)')
+ self.out('')
+ self.show_explicit(tweens)
+ self.out('')
+ self.out('Implicit Tween Chain (not used)')
+ self.out('')
+ self.show_implicit(tweens)
else:
self.out('"pyramid.tweens" config value NOT set '
'(implicitly ordered tweens used)')
self.out('')
- ordering.append((implicit, ''))
- for L, title in ordering:
- if title:
- self.out(title)
- self.out('')
- fmt = '%-10s %-30s'
- self.out(fmt % ('Position', 'Name'))
- self.out(fmt % ('-'*len('Position'), '-'*len('Name')))
- self.out(fmt % ('(implied)', 'main'))
- for pos, (name, item) in enumerate(L):
- self.out(fmt % (pos, name))
- self.out(fmt % ('(implied)', 'ingress'))
+ self.out('Implicit Tween Chain')
self.out('')
+ self.show_implicit(tweens)
diff --git a/pyramid/tests/test_paster.py b/pyramid/tests/test_paster.py
index be7aa386e..36c3a51be 100644
--- a/pyramid/tests/test_paster.py
+++ b/pyramid/tests/test_paster.py
@@ -853,15 +853,9 @@ class TestPTweensCommand(unittest.TestCase):
result = command.command()
self.assertEqual(result, None)
self.assertEqual(
- L,
- ['"pyramid.tweens" config value NOT set (implicitly ordered tweens used)',
- '',
- 'Position Name ',
- '-------- ---- ',
- '(implied) main ',
- '0 name ',
- '(implied) ingress ',
- ''])
+ L[0],
+ '"pyramid.tweens" config value NOT set (implicitly ordered tweens '
+ 'used)')
def test_command_implicit_and_explicit_tweens(self):
command = self._makeOne()
@@ -872,25 +866,8 @@ class TestPTweensCommand(unittest.TestCase):
result = command.command()
self.assertEqual(result, None)
self.assertEqual(
- L,
- ['"pyramid.tweens" config value set (explicitly ordered tweens used)',
- '',
- 'Explicit Tween Chain (used)',
- '',
- 'Position Name ',
- '-------- ---- ',
- '(implied) main ',
- '0 name2 ',
- '(implied) ingress ',
- '',
- 'Implicit Tween Chain (not used)',
- '',
- 'Position Name ',
- '-------- ---- ',
- '(implied) main ',
- '0 name ',
- '(implied) ingress ',
- ''])
+ L[0],
+ '"pyramid.tweens" config value set (explicitly ordered tweens used)')
def test__get_tweens(self):
command = self._makeOne()
@@ -901,6 +878,7 @@ class DummyTweens(object):
def __init__(self, implicit, explicit):
self._implicit = implicit
self.explicit = explicit
+ self.name_to_alias = {}
def implicit(self):
return self._implicit
diff --git a/pyramid/tests/test_tweens.py b/pyramid/tests/test_tweens.py
index c8c2e591c..127256c05 100644
--- a/pyramid/tests/test_tweens.py
+++ b/pyramid/tests/test_tweens.py
@@ -13,32 +13,75 @@ class TestTweens(unittest.TestCase):
self.assertEqual(tweens.explicit, [('name', 'factory'),
('name2', 'factory2')])
- def test_add_implicit(self):
+ def test_add_implicit_noaliases(self):
from pyramid.tweens import INGRESS
+ from pyramid.tweens import MAIN
+ D = {MAIN:MAIN, INGRESS:INGRESS}
tweens = self._makeOne()
tweens.add_implicit('name', 'factory')
- self.assertEqual(tweens.implicit_alias_names, ['name'])
- self.assertEqual(tweens.implicit_factories,
+ self.assertEqual(tweens.names, ['name'])
+ self.assertEqual(tweens.factories,
{'name':'factory'})
- self.assertEqual(tweens.implicit_ingress_alias_names, ['name'])
- self.assertEqual(tweens.implicit_order, [('name', INGRESS)])
+ self.assertEqual(tweens.alias_to_name, D)
+ self.assertEqual(tweens.name_to_alias, D)
+ self.assertEqual(tweens.order, [('name', INGRESS)])
+ self.assertEqual(tweens.ingress_alias_names, ['name'])
tweens.add_implicit('name2', 'factory2')
- self.assertEqual(tweens.implicit_alias_names, ['name', 'name2'])
- self.assertEqual(tweens.implicit_factories,
+ self.assertEqual(tweens.names, ['name', 'name2'])
+ self.assertEqual(tweens.factories,
{'name':'factory', 'name2':'factory2'})
- self.assertEqual(tweens.implicit_ingress_alias_names, ['name', 'name2'])
- self.assertEqual(tweens.implicit_order,
+ self.assertEqual(tweens.alias_to_name, D)
+ self.assertEqual(tweens.name_to_alias, D)
+ self.assertEqual(tweens.order,
[('name', INGRESS), ('name2', INGRESS)])
+ self.assertEqual(tweens.ingress_alias_names, ['name', 'name2'])
tweens.add_implicit('name3', 'factory3', below='name2')
- self.assertEqual(tweens.implicit_alias_names,
+ self.assertEqual(tweens.names,
['name', 'name2', 'name3'])
- self.assertEqual(tweens.implicit_factories,
+ self.assertEqual(tweens.factories,
{'name':'factory', 'name2':'factory2',
'name3':'factory3'})
- self.assertEqual(tweens.implicit_ingress_alias_names, ['name', 'name2'])
- self.assertEqual(tweens.implicit_order,
+ self.assertEqual(tweens.alias_to_name, D)
+ self.assertEqual(tweens.name_to_alias, D)
+ self.assertEqual(tweens.order,
[('name', INGRESS), ('name2', INGRESS),
('name2', 'name3')])
+ self.assertEqual(tweens.ingress_alias_names, ['name', 'name2'])
+
+ def test_add_implicit_withaliases(self):
+ from pyramid.tweens import INGRESS
+ from pyramid.tweens import MAIN
+ D = {MAIN:MAIN, INGRESS:INGRESS}
+ tweens = self._makeOne()
+ tweens.add_implicit('name1', 'factory', alias='n1')
+ self.assertEqual(tweens.names, ['name1'])
+ self.assertEqual(tweens.factories,
+ {'name1':'factory'})
+ self.assertEqual(tweens.alias_to_name['n1'], 'name1')
+ self.assertEqual(tweens.name_to_alias['name1'], 'n1')
+ self.assertEqual(tweens.order, [('n1', INGRESS)])
+ self.assertEqual(tweens.ingress_alias_names, ['n1'])
+ tweens.add_implicit('name2', 'factory2', alias='n2')
+ self.assertEqual(tweens.names, ['name1', 'name2'])
+ self.assertEqual(tweens.factories,
+ {'name1':'factory', 'name2':'factory2'})
+ self.assertEqual(tweens.alias_to_name['n2'], 'name2')
+ self.assertEqual(tweens.name_to_alias['name2'], 'n2')
+ self.assertEqual(tweens.order,
+ [('n1', INGRESS), ('n2', INGRESS)])
+ self.assertEqual(tweens.ingress_alias_names, ['n1', 'n2'])
+ tweens.add_implicit('name3', 'factory3', alias='n3', below='name2')
+ self.assertEqual(tweens.names,
+ ['name1', 'name2', 'name3'])
+ self.assertEqual(tweens.factories,
+ {'name1':'factory', 'name2':'factory2',
+ 'name3':'factory3'})
+ self.assertEqual(tweens.alias_to_name['n3'], 'name3')
+ self.assertEqual(tweens.name_to_alias['name3'], 'n3')
+ self.assertEqual(tweens.order,
+ [('n1', INGRESS), ('n2', INGRESS),
+ ('name2', 'n3')])
+ self.assertEqual(tweens.ingress_alias_names, ['n1', 'n2'])
def test___call___explicit(self):
tweens = self._makeOne()
@@ -55,9 +98,10 @@ class TestTweens(unittest.TestCase):
return handler
def factory2(handler, registry):
return '123'
- tweens.implicit_alias_names = ['name', 'name2']
- tweens.implicit_aliases = {'name':'name', 'name2':'name2'}
- tweens.implicit_factories = {'name':factory1, 'name2':factory2}
+ tweens.names = ['name', 'name2']
+ tweens.alias_to_name = {'name':'name', 'name2':'name2'}
+ tweens.name_to_alias = {'name':'name', 'name2':'name2'}
+ tweens.factories = {'name':factory1, 'name2':factory2}
self.assertEqual(tweens(None, None), '123')
def test___call___implicit_with_aliasnames_different_than_names(self):
@@ -66,9 +110,10 @@ class TestTweens(unittest.TestCase):
return handler
def factory2(handler, registry):
return '123'
- tweens.implicit_alias_names = ['foo1', 'foo2']
- tweens.implicit_aliases = {'foo1':'name', 'foo2':'name2'}
- tweens.implicit_factories = {'name':factory1, 'name2':factory2}
+ tweens.names = ['foo1', 'foo2']
+ tweens.alias_to_name = {'foo1':'name', 'foo2':'name2'}
+ tweens.name_to_alias = {'name':'foo1', 'name2':'foo2'}
+ tweens.factories = {'name':factory1, 'name2':factory2}
self.assertEqual(tweens(None, None), '123')
def test_implicit_ordering_1(self):
@@ -122,6 +167,24 @@ class TestTweens(unittest.TestCase):
('browserid', 'browserid_factory'),
('dbt', 'dbt_factory')])
+ def test_implicit_ordering_withaliases(self):
+ from pyramid.tweens import MAIN
+ tweens = self._makeOne()
+ add = tweens.add_implicit
+ add('exceptionview', 'excview_factory', alias='e', below=MAIN)
+ add('auth', 'auth_factory', atop='b')
+ add('retry', 'retry_factory', below='t', atop='exceptionview')
+ add('browserid', 'browserid_factory', alias='b')
+ add('txnmgr', 'txnmgr_factory', alias='t', atop='exceptionview')
+ add('dbt', 'dbt_factory')
+ self.assertEqual(tweens.implicit(),
+ [('txnmgr', 'txnmgr_factory'),
+ ('retry', 'retry_factory'),
+ ('exceptionview', 'excview_factory'),
+ ('auth', 'auth_factory'),
+ ('browserid', 'browserid_factory'),
+ ('dbt', 'dbt_factory')])
+
def test_implicit_ordering_missing_partial(self):
from pyramid.tweens import MAIN
tweens = self._makeOne()
diff --git a/pyramid/tweens.py b/pyramid/tweens.py
index ee46ec94a..c6e386bfe 100644
--- a/pyramid/tweens.py
+++ b/pyramid/tweens.py
@@ -61,34 +61,48 @@ class Tweens(object):
implements(ITweens)
def __init__(self):
self.explicit = []
- self.implicit_alias_names = []
- self.implicit_factories = {}
- self.implicit_order = []
- self.implicit_ingress_alias_names = []
- self.implicit_aliases = {}
+ self.names = []
+ self.factories = {}
+ self.order = []
+ self.ingress_alias_names = []
+ self.alias_to_name = {INGRESS:INGRESS, MAIN:MAIN}
+ self.name_to_alias = {INGRESS:INGRESS, MAIN:MAIN}
def add_explicit(self, name, factory):
self.explicit.append((name, factory))
def add_implicit(self, name, factory, alias=None, below=None, atop=None):
- if alias is None:
+ if alias is not None:
+ self.alias_to_name[alias] = name
+ self.name_to_alias[name] = alias
+ else:
alias = name
- self.implicit_aliases[alias] = name
- self.implicit_alias_names.append(alias)
- self.implicit_factories[name] = factory
+ self.names.append(name)
+ self.factories[name] = factory
if below is None and atop is None:
atop = INGRESS
- self.implicit_ingress_alias_names.append(alias)
+ self.ingress_alias_names.append(alias)
if below is not None:
- order = (below, alias)
- self.implicit_order.append(order)
+ self.order.append((below, alias))
if atop is not None:
- order = (alias, atop)
- self.implicit_order.append(order)
+ self.order.append((alias, atop))
def implicit(self):
+ order = []
roots = []
graph = {}
+ has_order = {}
+ aliases = [MAIN, INGRESS]
+ ingress_alias_names = self.ingress_alias_names[:]
+
+ for name in self.names:
+ aliases.append(self.name_to_alias.get(name, name))
+
+ for a, b in self.order:
+ # try to convert both a and b to an alias
+ a = self.name_to_alias.get(a, a)
+ b = self.name_to_alias.get(b, b)
+ order.append((a, b))
def add_node(graph, node):
if not graph.has_key(node):
@@ -101,37 +115,34 @@ class Tweens(object):
if tonode in roots:
roots.remove(tonode)
- aliases = [MAIN, INGRESS] + self.implicit_alias_names
-
- orders = {}
-
- for pos, (first, second) in enumerate(self.implicit_order):
+ # remove ordering information that mentions unknown names/aliases
+ for pos, (first, second) in enumerate(order):
has_first = first in aliases
has_second = second in aliases
if (not has_first) or (not has_second):
- self.implicit_order[pos] = None, None # FFF
+ order[pos] = None, None
else:
- orders[first] = orders[second] = True
+ has_order[first] = has_order[second] = True
for v in aliases:
# any alias that doesn't have an ordering after we detect all
# nodes with orders should get an ordering relative to INGRESS,
- # as if it were added with no below or atop
- if (not v in orders) and (v not in (INGRESS, MAIN)):
- self.implicit_order.append((v, INGRESS))
- self.implicit_ingress_alias_names.append(v)
+ # as if it were added with no below or atop in add_implicit
+ if (not v in has_order) and (v not in (INGRESS, MAIN)):
+ order.append((v, INGRESS))
+ ingress_alias_names.append(v)
add_node(graph, v)
- for a, b in self.implicit_order:
- if a is not None and b is not None: # see FFF above
+ for a, b in order:
+ if a is not None and b is not None: # deal with removed orders
add_arc(graph, a, b)
- def sortroots(name):
- # sort roots so that roots (and their children) that depend only on
- # the ingress sort nearer the end (nearer the ingress)
- if name in self.implicit_ingress_alias_names:
+ def sortroots(alias):
+ # sort roots so that roots (and their children) that depend only
+ # on the ingress sort nearer the end (nearer the ingress)
+ if alias in ingress_alias_names:
return 1
- children = graph[name][1:]
+ children = graph[alias][1:]
for child in children:
if sortroots(child) == 1:
return 1
@@ -164,17 +175,17 @@ class Tweens(object):
for alias in sorted_aliases:
if alias not in (MAIN, INGRESS):
- name = self.implicit_aliases[alias]
- result.append((name, self.implicit_factories[name]))
+ name = self.alias_to_name.get(alias, alias)
+ result.append((name, self.factories[name]))
return result
def __call__(self, handler, registry):
if self.explicit:
- factories = self.explicit
+ use = self.explicit
else:
- factories = self.implicit()
- for name, factory in factories:
+ use = self.implicit()
+ for name, factory in use:
handler = factory(handler, registry)
return handler
@@ -195,7 +206,7 @@ def tween_factory_name(factory):
'%s is not a suitable tween factory' % factory)
return name
-MAIN = 'main-->'
-INGRESS = '<--ingress'
+MAIN = 'MAIN'
+INGRESS = 'INGRESS'
EXCVIEW = tween_factory_name(excview_tween_factory)