diff options
| author | Chris McDonough <chrism@plope.com> | 2011-08-20 19:02:45 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-08-20 19:02:45 -0400 |
| commit | b397ac9cfb2f28ccda9c5779ffdce50a22f99d3c (patch) | |
| tree | 471c9e1ce49860cb030b61475f724d030db7dec3 | |
| parent | 449287942782a24dbe31a60ca791d677fd0ba003 (diff) | |
| download | pyramid-b397ac9cfb2f28ccda9c5779ffdce50a22f99d3c.tar.gz pyramid-b397ac9cfb2f28ccda9c5779ffdce50a22f99d3c.tar.bz2 pyramid-b397ac9cfb2f28ccda9c5779ffdce50a22f99d3c.zip | |
move configuration bits of tween stuff into config/tweens
| -rw-r--r-- | pyramid/config/tweens.py | 139 | ||||
| -rw-r--r-- | pyramid/tests/test_config/test_tweens.py (renamed from pyramid/tests/test_tweens.py) | 8 | ||||
| -rw-r--r-- | pyramid/tweens.py | 139 |
3 files changed, 142 insertions, 144 deletions
diff --git a/pyramid/config/tweens.py b/pyramid/config/tweens.py index 83067f0fe..46238b136 100644 --- a/pyramid/config/tweens.py +++ b/pyramid/config/tweens.py @@ -1,8 +1,9 @@ +from zope.interface import implements + from pyramid.interfaces import ITweens from pyramid.exceptions import ConfigurationError from pyramid.tweens import excview_tween_factory -from pyramid.tweens import Tweens from pyramid.tweens import MAIN, INGRESS, EXCVIEW from pyramid.config.util import action_method @@ -154,3 +155,139 @@ class TweensConfiguratorMixin(object): if not explicit and alias is not None: self.action(('tween', alias, explicit)) + +class CyclicDependencyError(Exception): + def __init__(self, cycles): + self.cycles = cycles + + def __str__(self): + L = [] + cycles = self.cycles + for cycle in cycles: + dependent = cycle + dependees = cycles[cycle] + L.append('%r sorts over %r' % (dependent, dependees)) + msg = 'Implicit tween ordering cycle:' + '; '.join(L) + return msg + +class Tweens(object): + implements(ITweens) + def __init__(self): + self.explicit = [] + self.names = [] + self.req_over = set() + self.req_under = set() + self.factories = {} + self.order = [] + 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, under=None, over=None): + if alias is None: + alias = name + self.alias_to_name[alias] = name + self.name_to_alias[name] = alias + self.names.append(name) + self.factories[name] = factory + if under is None and over is None: + under = INGRESS + if under is not None: + if not hasattr(under, '__iter__'): + under = (under,) + self.order += [(u, alias) for u in under] + self.req_under.add(alias) + if over is not None: + if not hasattr(over, '__iter__'): + over = (over,) + self.order += [(alias, o) for o in over] + self.req_over.add(alias) + + def implicit(self): + order = [(INGRESS, MAIN)] + roots = [] + graph = {} + aliases = [INGRESS, MAIN] + + for name in self.names: + aliases.append(self.name_to_alias[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(node): + if not graph.has_key(node): + roots.append(node) + graph[node] = [0] # 0 = number of arcs coming into this node + + def add_arc(fromnode, tonode): + graph[fromnode].append(tonode) + graph[tonode][0] += 1 + if tonode in roots: + roots.remove(tonode) + + for alias in aliases: + add_node(alias) + + has_over, has_under = set(), set() + for a, b in order: + if a in aliases and b in aliases: # deal with missing dependencies + add_arc(a, b) + has_over.add(a) + has_under.add(b) + + if not self.req_over.issubset(has_over): + raise ConfigurationError( + 'Detected tweens with no satisfied over dependencies: %s' + % (', '.join(sorted(self.req_over - has_over))) + ) + if not self.req_under.issubset(has_under): + raise ConfigurationError( + 'Detected tweens with no satisfied under dependencies: %s' + % (', '.join(sorted(self.req_under - has_under))) + ) + + sorted_aliases = [] + + while roots: + root = roots.pop(0) + sorted_aliases.append(root) + children = graph[root][1:] + for child in children: + arcs = graph[child][0] + arcs -= 1 + graph[child][0] = arcs + if arcs == 0: + roots.insert(0, child) + del graph[root] + + if graph: + # loop in input + cycledeps = {} + for k, v in graph.items(): + cycledeps[k] = v[1:] + raise CyclicDependencyError(cycledeps) + + result = [] + + for alias in sorted_aliases: + name = self.alias_to_name.get(alias, alias) + if name in self.names: + result.append((name, self.factories[name])) + + return result + + def __call__(self, handler, registry): + if self.explicit: + use = self.explicit + else: + use = self.implicit() + for name, factory in use[::-1]: + handler = factory(handler, registry) + return handler + diff --git a/pyramid/tests/test_tweens.py b/pyramid/tests/test_config/test_tweens.py index 67cfee8a9..c7098875e 100644 --- a/pyramid/tests/test_tweens.py +++ b/pyramid/tests/test_config/test_tweens.py @@ -2,7 +2,7 @@ import unittest class TestTweens(unittest.TestCase): def _makeOne(self): - from pyramid.tweens import Tweens + from pyramid.config.tweens import Tweens return Tweens() def test_add_explicit(self): @@ -353,7 +353,7 @@ class TestTweens(unittest.TestCase): self.assertRaises(ConfigurationError, tweens.implicit) def test_implicit_ordering_conflict_direct(self): - from pyramid.tweens import CyclicDependencyError + from pyramid.config.tweens import CyclicDependencyError tweens = self._makeOne() add = tweens.add_implicit add('browserid', 'browserid_factory') @@ -361,7 +361,7 @@ class TestTweens(unittest.TestCase): self.assertRaises(CyclicDependencyError, tweens.implicit) def test_implicit_ordering_conflict_indirect(self): - from pyramid.tweens import CyclicDependencyError + from pyramid.config.tweens import CyclicDependencyError tweens = self._makeOne() add = tweens.add_implicit add('browserid', 'browserid_factory') @@ -371,7 +371,7 @@ class TestTweens(unittest.TestCase): class TestCyclicDependencyError(unittest.TestCase): def _makeOne(self, cycles): - from pyramid.tweens import CyclicDependencyError + from pyramid.config.tweens import CyclicDependencyError return CyclicDependencyError(cycles) def test___str__(self): diff --git a/pyramid/tweens.py b/pyramid/tweens.py index b53942a36..d12a57339 100644 --- a/pyramid/tweens.py +++ b/pyramid/tweens.py @@ -1,11 +1,8 @@ import sys -from pyramid.exceptions import ConfigurationError from pyramid.interfaces import IExceptionViewClassifier from pyramid.interfaces import IView -from pyramid.interfaces import ITweens from zope.interface import providedBy -from zope.interface import implements def excview_tween_factory(handler, registry): """ A :term:`tween` factory which produces a tween that catches an @@ -46,142 +43,6 @@ def excview_tween_factory(handler, registry): return excview_tween -class CyclicDependencyError(Exception): - def __init__(self, cycles): - self.cycles = cycles - - def __str__(self): - L = [] - cycles = self.cycles - for cycle in cycles: - dependent = cycle - dependees = cycles[cycle] - L.append('%r sorts over %r' % (dependent, dependees)) - msg = 'Implicit tween ordering cycle:' + '; '.join(L) - return msg - -class Tweens(object): - implements(ITweens) - def __init__(self): - self.explicit = [] - self.names = [] - self.req_over = set() - self.req_under = set() - self.factories = {} - self.order = [] - 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, under=None, over=None): - if alias is None: - alias = name - self.alias_to_name[alias] = name - self.name_to_alias[name] = alias - self.names.append(name) - self.factories[name] = factory - if under is None and over is None: - under = INGRESS - if under is not None: - if not hasattr(under, '__iter__'): - under = (under,) - self.order += [(u, alias) for u in under] - self.req_under.add(alias) - if over is not None: - if not hasattr(over, '__iter__'): - over = (over,) - self.order += [(alias, o) for o in over] - self.req_over.add(alias) - - def implicit(self): - order = [(INGRESS, MAIN)] - roots = [] - graph = {} - aliases = [INGRESS, MAIN] - - for name in self.names: - aliases.append(self.name_to_alias[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(node): - if not graph.has_key(node): - roots.append(node) - graph[node] = [0] # 0 = number of arcs coming into this node - - def add_arc(fromnode, tonode): - graph[fromnode].append(tonode) - graph[tonode][0] += 1 - if tonode in roots: - roots.remove(tonode) - - for alias in aliases: - add_node(alias) - - has_over, has_under = set(), set() - for a, b in order: - if a in aliases and b in aliases: # deal with missing dependencies - add_arc(a, b) - has_over.add(a) - has_under.add(b) - - if not self.req_over.issubset(has_over): - raise ConfigurationError( - 'Detected tweens with no satisfied over dependencies: %s' - % (', '.join(sorted(self.req_over - has_over))) - ) - if not self.req_under.issubset(has_under): - raise ConfigurationError( - 'Detected tweens with no satisfied under dependencies: %s' - % (', '.join(sorted(self.req_under - has_under))) - ) - - sorted_aliases = [] - - while roots: - root = roots.pop(0) - sorted_aliases.append(root) - children = graph[root][1:] - for child in children: - arcs = graph[child][0] - arcs -= 1 - graph[child][0] = arcs - if arcs == 0: - roots.insert(0, child) - del graph[root] - - if graph: - # loop in input - cycledeps = {} - for k, v in graph.items(): - cycledeps[k] = v[1:] - raise CyclicDependencyError(cycledeps) - - result = [] - - for alias in sorted_aliases: - name = self.alias_to_name.get(alias, alias) - if name in self.names: - result.append((name, self.factories[name])) - - return result - - def __call__(self, handler, registry): - if self.explicit: - use = self.explicit - else: - use = self.implicit() - for name, factory in use[::-1]: - handler = factory(handler, registry) - return handler - MAIN = 'MAIN' INGRESS = 'INGRESS' EXCVIEW = 'excview' - |
