summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrforkel <robert.forkel@gulp.de>2012-06-26 08:40:34 +0200
committerMichael Merickel <michael@merickel.org>2012-11-04 18:59:18 -0600
commit76c9c20478f53c36d5ded59191e335dba1d47da6 (patch)
treefbe8fad8b06a9486e135d4b9dd1d18bc9ae2e0cf
parent20b1a19653de95e1adfa864a4f9ef6b2522e3409 (diff)
downloadpyramid-76c9c20478f53c36d5ded59191e335dba1d47da6.tar.gz
pyramid-76c9c20478f53c36d5ded59191e335dba1d47da6.tar.bz2
pyramid-76c9c20478f53c36d5ded59191e335dba1d47da6.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 b01d17efd..b17619356 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -837,11 +837,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)``.
@@ -1071,7 +1072,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 575d8c738..a62e5f2ea 100644
--- a/pyramid/tests/test_config/test_views.py
+++ b/pyramid/tests/test_config/test_views.py
@@ -185,6 +185,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 df9d03490..0af941e0d 100644
--- a/pyramid/tests/test_view.py
+++ b/pyramid/tests/test_view.py
@@ -372,6 +372,10 @@ class TestViewConfigDecorator(unittest.TestCase):
def test_create_with_other_predicates(self):
decorator = self._makeOne(foo=1)
self.assertEqual(decorator.foo, 1)
+
+ 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()