summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrforkel <robert.forkel@gulp.de>2012-06-26 08:40:34 +0200
committerrforkel <robert.forkel@gulp.de>2012-06-26 08:40:34 +0200
commit6454a73a9ea0b00f3881e003efda3048e8407a5f (patch)
treeb541844821884df94962eb8b644635c9dfc3dcdc
parent71b473705f73b12a35422d3aa257906e4a99d853 (diff)
downloadpyramid-6454a73a9ea0b00f3881e003efda3048e8407a5f.tar.gz
pyramid-6454a73a9ea0b00f3881e003efda3048e8407a5f.tar.bz2
pyramid-6454a73a9ea0b00f3881e003efda3048e8407a5f.zip
Added support for passing multiple decorators to add_view.
-rw-r--r--pyramid/config/views.py20
-rw-r--r--pyramid/scaffolds/copydir.py2
-rw-r--r--pyramid/tests/test_config/test_views.py22
-rw-r--r--pyramid/tests/test_view.py4
4 files changed, 43 insertions, 5 deletions
diff --git a/pyramid/config/views.py b/pyramid/config/views.py
index 9e9b5321b..b00c4b9f2 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -807,11 +807,12 @@ class ViewsConfiguratorMixin(object):
decorator
- A :term:`dotted Python name` to function (or the function itself)
+ A :term:`dotted Python name` to function (or the function itself,
+ or a list or tuple of the aforementioned)
which will be used to decorate the registered :term:`view
- callable`. The decorator function will be called with the view
+ callable`. The decorator function(s) will be called with the view
callable as a single argument. The view callable it is passed will
- accept ``(context, request)``. The decorator must return a
+ accept ``(context, request)``. The decorator(s) must return a
replacement view callable which also accepts ``(context,
request)``.
@@ -979,7 +980,18 @@ class ViewsConfiguratorMixin(object):
for_ = self.maybe_dotted(for_)
containment = self.maybe_dotted(containment)
mapper = self.maybe_dotted(mapper)
- decorator = self.maybe_dotted(decorator)
+
+ def combine(*decorators):
+ def decorated(view_callable):
+ for decorator in decorators:
+ view_callable = decorator(view_callable)
+ return view_callable
+ return decorated
+
+ if isinstance(decorator, (tuple, list)):
+ decorator = combine(*map(self.maybe_dotted, decorator))
+ else:
+ decorator = self.maybe_dotted(decorator)
if not view:
if renderer:
diff --git a/pyramid/scaffolds/copydir.py b/pyramid/scaffolds/copydir.py
index d55ea165a..ba0988523 100644
--- a/pyramid/scaffolds/copydir.py
+++ b/pyramid/scaffolds/copydir.py
@@ -245,7 +245,7 @@ Responses:
def makedirs(dir, verbosity, pad):
parent = os.path.dirname(os.path.abspath(dir))
if not os.path.exists(parent):
- makedirs(parent, verbosity, pad)
+ makedirs(parent, verbosity, pad) # pragma: no cover
os.mkdir(dir)
def substitute_filename(fn, vars):
diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py
index 9b46f83c9..4435d341e 100644
--- a/pyramid/tests/test_config/test_views.py
+++ b/pyramid/tests/test_config/test_views.py
@@ -184,6 +184,28 @@ class TestViewsConfigurationMixin(unittest.TestCase):
result = wrapper(None, None)
self.assertEqual(result, 'OK')
+ def test_add_view_with_decorator_tuple(self):
+ from pyramid.renderers import null_renderer
+ def view(request):
+ """ ABC """
+ return 'OK'
+ def view_wrapper1(fn):
+ def inner(context, request):
+ return 'wrapped1' + fn(context, request)
+ return inner
+ def view_wrapper2(fn):
+ def inner(context, request):
+ return 'wrapped2' + fn(context, request)
+ return inner
+ config = self._makeOne(autocommit=True)
+ config.add_view(view=view, decorator=(view_wrapper1, view_wrapper2),
+ renderer=null_renderer)
+ wrapper = self._getViewCallable(config)
+ self.assertFalse(wrapper is view)
+ self.assertEqual(wrapper.__doc__, view.__doc__)
+ result = wrapper(None, None)
+ self.assertEqual(result, 'wrapped2wrapped1OK')
+
def test_add_view_with_http_cache(self):
import datetime
from pyramid.response import Response
diff --git a/pyramid/tests/test_view.py b/pyramid/tests/test_view.py
index a105adb70..35fa132a8 100644
--- a/pyramid/tests/test_view.py
+++ b/pyramid/tests/test_view.py
@@ -371,6 +371,10 @@ class TestViewConfigDecorator(unittest.TestCase):
self.assertEqual(decorator.mapper, 'mapper')
self.assertEqual(decorator.decorator, 'decorator')
self.assertEqual(decorator.match_param, 'match_param')
+
+ def test_create_decorator_tuple(self):
+ decorator = self._makeOne(decorator=('decorator1', 'decorator2'))
+ self.assertEqual(decorator.decorator, ('decorator1', 'decorator2'))
def test_call_function(self):
decorator = self._makeOne()