Ticket #5701: dj-functools-decorators.diff

File dj-functools-decorators.diff, 9.2 KB (added by jdunck, 7 years ago)

patch against 6454

  • django/views/decorators/http.py

     
    33"""
    44
    55from django.utils.decorators import decorator_from_middleware
     6from django.utils.functional import wraps
    67from django.middleware.http import ConditionalGetMiddleware
    78from django.http import HttpResponseNotAllowed
    89
     
    2425            if request.method not in request_method_list:
    2526                return HttpResponseNotAllowed(request_method_list)
    2627            return func(request, *args, **kwargs)
    27         return inner
     28        return wraps(func)(inner)
    2829    return decorator
    2930
    3031require_GET = require_http_methods(["GET"])
  • django/views/decorators/vary.py

     
    11from django.utils.cache import patch_vary_headers
     2from django.utils.functional import wraps
    23
    34def vary_on_headers(*headers):
    45    """
     
    1617            response = func(*args, **kwargs)
    1718            patch_vary_headers(response, headers)
    1819            return response
    19         return inner_func
     20        return wraps(func)(inner_func)
    2021    return decorator
    2122
    2223def vary_on_cookie(func):
     
    3233        response = func(*args, **kwargs)
    3334        patch_vary_headers(response, ('Cookie',))
    3435        return response
    35     return inner_func
     36    return wraps(func)(inner_func)
  • django/views/decorators/cache.py

     
    1313
    1414from django.utils.decorators import decorator_from_middleware
    1515from django.utils.cache import patch_cache_control, add_never_cache_headers
     16from django.utils.functional import wraps
    1617from django.middleware.cache import CacheMiddleware
    1718
    1819cache_page = decorator_from_middleware(CacheMiddleware)
     
    2627            patch_cache_control(response, **kwargs)
    2728            return response
    2829
    29         return _cache_controlled
     30        return wraps(viewfunc)(_cache_controlled)
    3031
    3132    return _cache_controller
    3233
     
    3940        response = view_func(request, *args, **kwargs)
    4041        add_never_cache_headers(response)
    4142        return response
    42     return _wrapped_view_func
     43    return wraps(view_func)(_wrapped_view_func)
  • django/utils/functional.py

     
    33        return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs))
    44    return _curried
    55
     6#Begin from Python 2.5 functools.py =================================
     7#N.B. swapping ``partial`` for ``curry``
     8# to maintain backwards-compatibility in Django.
     9
     10# update_wrapper() and wraps() are tools to help write
     11# wrapper functions that can handle naive introspection
     12
     13WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
     14WRAPPER_UPDATES = ('__dict__',)
     15def update_wrapper(wrapper,
     16                   wrapped,
     17                   assigned = WRAPPER_ASSIGNMENTS,
     18                   updated = WRAPPER_UPDATES):
     19    """Update a wrapper function to look like the wrapped function
     20
     21       wrapper is the function to be updated
     22       wrapped is the original function
     23       assigned is a tuple naming the attributes assigned directly
     24       from the wrapped function to the wrapper function (defaults to
     25       functools.WRAPPER_ASSIGNMENTS)
     26       updated is a tuple naming the attributes off the wrapper that
     27       are updated with the corresponding attribute from the wrapped
     28       function (defaults to functools.WRAPPER_UPDATES)
     29    """
     30    for attr in assigned:
     31        setattr(wrapper, attr, getattr(wrapped, attr))
     32    for attr in updated:
     33        getattr(wrapper, attr).update(getattr(wrapped, attr))
     34    # Return the wrapper so this can be used as a decorator via curry()
     35    return wrapper
     36
     37def wraps(wrapped,
     38          assigned = WRAPPER_ASSIGNMENTS,
     39          updated = WRAPPER_UPDATES):
     40    """Decorator factory to apply update_wrapper() to a wrapper function
     41
     42       Returns a decorator that invokes update_wrapper() with the decorated
     43       function as the wrapper argument and the arguments to wraps() as the
     44       remaining arguments. Default arguments are as for update_wrapper().
     45       This is a convenience function to simplify applying curry() to
     46       update_wrapper().
     47    """
     48    return curry(update_wrapper, wrapped=wrapped,
     49                   assigned=assigned, updated=updated)
     50
     51#End from Python 2.5 functools.py ===================================
     52
    653def memoize(func, cache, num_args):
    754    """
    855    Wrap a function so that results for any argument tuple are stored in
  • django/utils/decorators.py

     
    11"Functions that help with dynamically creating decorators for views."
    22
    33import types
     4from django.utils.functional import wraps
    45
    56def decorator_from_middleware(middleware_class):
    67    """
     
    5354                if result is not None:
    5455                    return result
    5556            return response
    56         return _wrapped_view
     57        return wraps(view_func)(_wrapped_view)
    5758    return _decorator_from_middleware
  • django/contrib/admin/views/decorators.py

     
    44from django.contrib.auth import authenticate, login
    55from django.shortcuts import render_to_response
    66from django.utils.translation import ugettext_lazy, ugettext as _
     7from django.utils.functional import wraps
    78import base64, datetime, md5
    89import cPickle as pickle
    910
     
    103104            else:
    104105                return _display_login_form(request, ERROR_MESSAGE)
    105106
    106     return _checklogin
     107    return wraps(view_func)(_checklogin)
     108 No newline at end of file
  • django/contrib/auth/decorators.py

     
    11from django.contrib.auth import REDIRECT_FIELD_NAME
    22from django.http import HttpResponseRedirect
    33from django.utils.http import urlquote
     4from django.utils.functional import wraps
    45
    56def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
    67    """
     
    1920        _checklogin.__doc__ = view_func.__doc__
    2021        _checklogin.__dict__ = view_func.__dict__
    2122
    22         return _checklogin
     23        return wraps(view_func)(_checklogin)
    2324    return _dec
    2425
    2526def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME):
  • tests/regressiontests/decorators/tests.py

     
     1"""
     2>>> fully_decorated.__module__
     3'regressiontests.decorators.tests'
     4>>> fully_decorated.__name__
     5'fully_decorated'
     6>>> fully_decorated.__doc__
     7'Expected __doc__'
     8>>> fully_decorated.__dict__['anything']
     9'Expected __dict__'
     10"""
     11from django.views.decorators.http import require_http_methods
     12from django.views.decorators.vary import vary_on_headers, vary_on_cookie
     13from django.views.decorators.cache import cache_page, never_cache, cache_control
     14from django.contrib.auth.decorators import user_passes_test
     15from django.contrib.admin.views.decorators import staff_member_required
     16
     17def fully_decorated(request):
     18    """Expected __doc__"""
     19    return HttpResponse('<html><body>dummy</body></html>')
     20fully_decorated.anything = "Expected __dict__"
     21
     22fully_decorated = require_http_methods(["GET"])(fully_decorated)
     23
     24fully_decorated = vary_on_headers('Accept-language')(fully_decorated)
     25fully_decorated = vary_on_cookie(fully_decorated)
     26
     27fully_decorated = cache_page(60*15)(fully_decorated)
     28fully_decorated = cache_control(private=True)(fully_decorated)
     29fully_decorated = never_cache(fully_decorated)
     30
     31fully_decorated = user_passes_test(lambda u:True)(fully_decorated)
     32fully_decorated = staff_member_required(fully_decorated)
     33
     34if __name__ == "__main__":
     35    import doctest
     36    doctest.testmod()
  • tests/regressiontests/views/views.py

     
    44def index_page(request):
    55    """Dummy index page"""
    66    return HttpResponse('<html><body>Dummy page</body></html>')
    7 
     7   
Back to Top