Changeset 7153
- Timestamp:
- 02/25/08 00:02:35 (6 months ago)
- Files:
-
- django/trunk/django/contrib/admin/views/decorators.py (modified) (3 diffs)
- django/trunk/django/contrib/auth/decorators.py (modified) (2 diffs)
- django/trunk/django/template/defaultfilters.py (modified) (2 diffs)
- django/trunk/django/utils/decorators.py (modified) (2 diffs)
- django/trunk/django/utils/functional.py (modified) (4 diffs)
- django/trunk/django/views/decorators/cache.py (modified) (3 diffs)
- django/trunk/django/views/decorators/http.py (modified) (2 diffs)
- django/trunk/django/views/decorators/vary.py (modified) (3 diffs)
- django/trunk/tests/regressiontests/decorators (added)
- django/trunk/tests/regressiontests/decorators/models.py (added)
- django/trunk/tests/regressiontests/decorators/tests.py (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/contrib/admin/views/decorators.py
r7131 r7153 1 import base64 2 import md5 3 import cPickle as pickle 4 try: 5 from functools import wraps 6 except ImportError: 7 from django.utils.functional import wraps # Python 2.3, 2.4 fallback. 8 1 9 from django import http, template 2 10 from django.conf import settings … … 6 14 from django.utils.translation import ugettext_lazy, ugettext as _ 7 15 from django.utils.safestring import mark_safe 8 import base64, md59 import cPickle as pickle10 16 11 17 ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.") … … 105 111 return _display_login_form(request, ERROR_MESSAGE) 106 112 107 return _checklogin113 return wraps(view_func)(_checklogin) django/trunk/django/contrib/auth/decorators.py
r6659 r7153 1 try: 2 from functools import wraps, update_wrapper 3 except ImportError: 4 from django.utils.functional import wraps, update_wrapper # Python 2.3, 2.4 fallback. 5 1 6 from django.contrib.auth import REDIRECT_FIELD_NAME 2 7 from django.http import HttpResponseRedirect … … 52 57 self.login_url = login_url 53 58 self.redirect_field_name = redirect_field_name 54 self.__name__ = view_func.__name__59 update_wrapper(self, view_func) 55 60 56 61 def __get__(self, obj, cls=None): django/trunk/django/template/defaultfilters.py
r7033 r7153 3 3 import re 4 4 import random as random_module 5 try: 6 from functools import wraps 7 except ImportError: 8 from django.utils.functional import wraps # Python 2.3, 2.4 fallback. 5 9 6 10 from django.template import Variable, Library … … 36 40 if hasattr(func, attr): 37 41 setattr(_dec, attr, getattr(func, attr)) 38 return _dec42 return wraps(func)(_dec) 39 43 40 44 ################### django/trunk/django/utils/decorators.py
r5631 r7153 2 2 3 3 import types 4 try: 5 from functools import wraps 6 except ImportError: 7 from django.utils.functional import wraps # Python 2.3, 2.4 fallback. 4 8 5 9 def decorator_from_middleware(middleware_class): … … 54 58 return result 55 59 return response 56 return _wrapped_view60 return wraps(view_func)(_wrapped_view) 57 61 return _decorator_from_middleware django/trunk/django/utils/functional.py
r6587 r7153 1 # License for code in this file that was taken from Python 2.5. 2 3 # PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 4 # -------------------------------------------- 5 # 6 # 1. This LICENSE AGREEMENT is between the Python Software Foundation 7 # ("PSF"), and the Individual or Organization ("Licensee") accessing and 8 # otherwise using this software ("Python") in source or binary form and 9 # its associated documentation. 10 # 11 # 2. Subject to the terms and conditions of this License Agreement, PSF 12 # hereby grants Licensee a nonexclusive, royalty-free, world-wide 13 # license to reproduce, analyze, test, perform and/or display publicly, 14 # prepare derivative works, distribute, and otherwise use Python 15 # alone or in any derivative version, provided, however, that PSF's 16 # License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 17 # 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation; 18 # All Rights Reserved" are retained in Python alone or in any derivative 19 # version prepared by Licensee. 20 # 21 # 3. In the event Licensee prepares a derivative work that is based on 22 # or incorporates Python or any part thereof, and wants to make 23 # the derivative work available to others as provided herein, then 24 # Licensee hereby agrees to include in any such work a brief summary of 25 # the changes made to Python. 26 # 27 # 4. PSF is making Python available to Licensee on an "AS IS" 28 # basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR 29 # IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND 30 # DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS 31 # FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT 32 # INFRINGE ANY THIRD PARTY RIGHTS. 33 # 34 # 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 35 # FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS 36 # A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, 37 # OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 38 # 39 # 6. This License Agreement will automatically terminate upon a material 40 # breach of its terms and conditions. 41 # 42 # 7. Nothing in this License Agreement shall be deemed to create any 43 # relationship of agency, partnership, or joint venture between PSF and 44 # Licensee. This License Agreement does not grant permission to use PSF 45 # trademarks or trade name in a trademark sense to endorse or promote 46 # products or services of Licensee, or any third party. 47 # 48 # 8. By copying, installing or otherwise using Python, Licensee 49 # agrees to be bound by the terms and conditions of this License 50 # Agreement. 51 52 1 53 def curry(_curried_func, *args, **kwargs): 2 54 def _curried(*moreargs, **morekwargs): 3 55 return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs)) 4 56 return _curried 57 58 ### Begin from Python 2.5 functools.py ######################################## 59 60 # Summary of changes made to the Python 2.5 code below: 61 # * swapped ``partial`` for ``curry`` to maintain backwards-compatibility 62 # in Django. 63 # * Wrapped the ``setattr`` call in ``update_wrapper`` with a try-except 64 # block to make it compatible with Python 2.3, which doesn't allow 65 # assigning to ``__name__``. 66 67 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation. 68 # All Rights Reserved. 69 70 ############################################################################### 71 72 # update_wrapper() and wraps() are tools to help write 73 # wrapper functions that can handle naive introspection 74 75 WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__') 76 WRAPPER_UPDATES = ('__dict__',) 77 def update_wrapper(wrapper, 78 wrapped, 79 assigned = WRAPPER_ASSIGNMENTS, 80 updated = WRAPPER_UPDATES): 81 """Update a wrapper function to look like the wrapped function 82 83 wrapper is the function to be updated 84 wrapped is the original function 85 assigned is a tuple naming the attributes assigned directly 86 from the wrapped function to the wrapper function (defaults to 87 functools.WRAPPER_ASSIGNMENTS) 88 updated is a tuple naming the attributes off the wrapper that 89 are updated with the corresponding attribute from the wrapped 90 function (defaults to functools.WRAPPER_UPDATES) 91 """ 92 for attr in assigned: 93 try: 94 setattr(wrapper, attr, getattr(wrapped, attr)) 95 except TypeError: # Python 2.3 doesn't allow assigning to __name__. 96 pass 97 for attr in updated: 98 getattr(wrapper, attr).update(getattr(wrapped, attr)) 99 # Return the wrapper so this can be used as a decorator via curry() 100 return wrapper 101 102 def wraps(wrapped, 103 assigned = WRAPPER_ASSIGNMENTS, 104 updated = WRAPPER_UPDATES): 105 """Decorator factory to apply update_wrapper() to a wrapper function 106 107 Returns a decorator that invokes update_wrapper() with the decorated 108 function as the wrapper argument and the arguments to wraps() as the 109 remaining arguments. Default arguments are as for update_wrapper(). 110 This is a convenience function to simplify applying curry() to 111 update_wrapper(). 112 """ 113 return curry(update_wrapper, wrapped=wrapped, 114 assigned=assigned, updated=updated) 115 116 ### End from Python 2.5 functools.py ########################################## 5 117 6 118 def memoize(func, cache, num_args): … … 19 131 cache[mem_args] = result 20 132 return result 21 return wrap per133 return wraps(func)(wrapper) 22 134 23 135 class Promise(object): … … 111 223 return __proxy__(args, kw) 112 224 113 return __wrapper__225 return wraps(func)(__wrapper__) 114 226 115 227 def allow_lazy(func, *resultclasses): … … 127 239 return func(*args, **kwargs) 128 240 return lazy(func, *resultclasses)(*args, **kwargs) 129 return wrap per241 return wraps(func)(wrapper) django/trunk/django/views/decorators/cache.py
r4265 r7153 11 11 account on caching -- just like the middleware does. 12 12 """ 13 14 try: 15 from functools import wraps 16 except ImportError: 17 from django.utils.functional import wraps # Python 2.3, 2.4 fallback. 13 18 14 19 from django.utils.decorators import decorator_from_middleware … … 27 32 return response 28 33 29 return _cache_controlled34 return wraps(viewfunc)(_cache_controlled) 30 35 31 36 return _cache_controller … … 40 45 add_never_cache_headers(response) 41 46 return response 42 return _wrapped_view_func47 return wraps(view_func)(_wrapped_view_func) django/trunk/django/views/decorators/http.py
r4265 r7153 2 2 Decorators for views based on HTTP headers. 3 3 """ 4 5 try: 6 from functools import wraps 7 except ImportError: 8 from django.utils.functional import wraps # Python 2.3, 2.4 fallback. 4 9 5 10 from django.utils.decorators import decorator_from_middleware … … 25 30 return HttpResponseNotAllowed(request_method_list) 26 31 return func(request, *args, **kwargs) 27 return inner32 return wraps(func)(inner) 28 33 return decorator 29 34 django/trunk/django/views/decorators/vary.py
r4265 r7153 1 try: 2 from functools import wraps 3 except ImportError: 4 from django.utils.functional import wraps # Python 2.3, 2.4 fallback. 5 1 6 from django.utils.cache import patch_vary_headers 2 7 … … 17 22 patch_vary_headers(response, headers) 18 23 return response 19 return inner_func24 return wraps(func)(inner_func) 20 25 return decorator 21 26 … … 33 38 patch_vary_headers(response, ('Cookie',)) 34 39 return response 35 return inner_func40 return wraps(func)(inner_func)
