Chaining Decorators

Pyramid has a decorator= argument to its view configuration. It accepts a single decorator that will wrap the mapped view callable represented by the view configuration. That means that, no matter what the signature and return value of the original view callable, the decorated view callable will receive two arguments: context and request and will return a response object:

 1# the decorator
 3def decorator(view_callable):
 4    def inner(context, request):
 5        return view_callable(context, request)
 6    return inner
 8# the view configuration
10@view_config(decorator=decorator, renderer='json')
11def myview(request):
12    return {'a':1}

But the decorator argument only takes a single decorator. What happens if you want to use more than one decorator? You can chain them together:

 1def combine(*decorators):
 2    def floo(view_callable):
 3        for decorator in decorators:
 4            view_callable = decorator(view_callable)
 5        return view_callable
 6    return floo
 8def decorator1(view_callable):
 9    def inner(context, request):
10        return view_callable(context, request)
11    return inner
13def decorator2(view_callable):
14    def inner(context, request):
15        return view_callable(context, request)
16    return inner
18def decorator3(view_callable):
19    def inner(context, request):
20        return view_callable(context, request)
21    return inner
23alldecs = combine(decorator1, decorator2, decorator3)
24two_and_three = combine(decorator2, decorator3)
25one_and_three = combine(decorator1, decorator3)
27@view_config(decorator=alldecs, renderer='json')
28def myview(request):
29    return {'a':1}