summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-08-20 19:02:45 -0400
committerChris McDonough <chrism@plope.com>2011-08-20 19:02:45 -0400
commitb397ac9cfb2f28ccda9c5779ffdce50a22f99d3c (patch)
tree471c9e1ce49860cb030b61475f724d030db7dec3
parent449287942782a24dbe31a60ca791d677fd0ba003 (diff)
downloadpyramid-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.py139
-rw-r--r--pyramid/tests/test_config/test_tweens.py (renamed from pyramid/tests/test_tweens.py)8
-rw-r--r--pyramid/tweens.py139
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'
-