diff options
| author | Chris McDonough <chrism@plope.com> | 2011-08-08 02:39:40 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-08-08 02:39:40 -0400 |
| commit | fd78f1b38496e2eda00e6efa08a52fdb7d922b99 (patch) | |
| tree | fbc4819e28ae2943e20378ab99c4d5175a56e5c9 | |
| parent | 06b15bf2024b553556ab8a56c185ec7229d20ed8 (diff) | |
| download | pyramid-fd78f1b38496e2eda00e6efa08a52fdb7d922b99.tar.gz pyramid-fd78f1b38496e2eda00e6efa08a52fdb7d922b99.tar.bz2 pyramid-fd78f1b38496e2eda00e6efa08a52fdb7d922b99.zip | |
add tween aliases
| -rw-r--r-- | pyramid/config.py | 36 | ||||
| -rw-r--r-- | pyramid/paster.py | 52 | ||||
| -rw-r--r-- | pyramid/tests/test_paster.py | 34 | ||||
| -rw-r--r-- | pyramid/tests/test_tweens.py | 101 | ||||
| -rw-r--r-- | pyramid/tweens.py | 89 |
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) |
