diff -r 8d941af65caf -r 77b6da96e6f1 web/lib/django/utils/decorators.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/lib/django/utils/decorators.py Wed Jun 02 18:57:35 2010 +0200 @@ -0,0 +1,90 @@ +"Functions that help with dynamically creating decorators for views." + +import types +try: + from functools import wraps, update_wrapper, WRAPPER_ASSIGNMENTS +except ImportError: + from django.utils.functional import wraps, update_wrapper, WRAPPER_ASSIGNMENTS # Python 2.4 fallback. + + +def method_decorator(decorator): + """ + Converts a function decorator into a method decorator + """ + def _dec(func): + def _wrapper(self, *args, **kwargs): + def bound_func(*args2, **kwargs2): + return func(self, *args2, **kwargs2) + # bound_func has the signature that 'decorator' expects i.e. no + # 'self' argument, but it is a closure over self so it can call + # 'func' correctly. + return decorator(bound_func)(*args, **kwargs) + return wraps(func)(_wrapper) + update_wrapper(_dec, decorator) + # Change the name to aid debugging. + _dec.__name__ = 'method_decorator(%s)' % decorator.__name__ + return _dec + + +def decorator_from_middleware_with_args(middleware_class): + """ + Like decorator_from_middleware, but returns a function + that accepts the arguments to be passed to the middleware_class. + Use like:: + + cache_page = decorator_from_middleware_with_args(CacheMiddleware) + # ... + + @cache_page(3600) + def my_view(request): + # ... + """ + return make_middleware_decorator(middleware_class) + + +def decorator_from_middleware(middleware_class): + """ + Given a middleware class (not an instance), returns a view decorator. This + lets you use middleware functionality on a per-view basis. The middleware + is created with no params passed. + """ + return make_middleware_decorator(middleware_class)() + + +def available_attrs(fn): + """ + Return the list of functools-wrappable attributes on a callable. + This is required as a workaround for http://bugs.python.org/issue3445. + """ + return tuple(a for a in WRAPPER_ASSIGNMENTS if hasattr(fn, a)) + + +def make_middleware_decorator(middleware_class): + def _make_decorator(*m_args, **m_kwargs): + middleware = middleware_class(*m_args, **m_kwargs) + def _decorator(view_func): + def _wrapped_view(request, *args, **kwargs): + if hasattr(middleware, 'process_request'): + result = middleware.process_request(request) + if result is not None: + return result + if hasattr(middleware, 'process_view'): + result = middleware.process_view(request, view_func, args, kwargs) + if result is not None: + return result + try: + response = view_func(request, *args, **kwargs) + except Exception, e: + if hasattr(middleware, 'process_exception'): + result = middleware.process_exception(request, e) + if result is not None: + return result + raise + if hasattr(middleware, 'process_response'): + result = middleware.process_response(request, response) + if result is not None: + return result + return response + return wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view) + return _decorator + return _make_decorator