00001 # License for code in this file that was taken from Python 2.5. 00002 00003 # PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 00004 # -------------------------------------------- 00005 # 00006 # 1. This LICENSE AGREEMENT is between the Python Software Foundation 00007 # ("PSF"), and the Individual or Organization ("Licensee") accessing and 00008 # otherwise using this software ("Python") in source or binary form and 00009 # its associated documentation. 00010 # 00011 # 2. Subject to the terms and conditions of this License Agreement, PSF 00012 # hereby grants Licensee a nonexclusive, royalty-free, world-wide 00013 # license to reproduce, analyze, test, perform and/or display publicly, 00014 # prepare derivative works, distribute, and otherwise use Python 00015 # alone or in any derivative version, provided, however, that PSF's 00016 # License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 00017 # 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation; 00018 # All Rights Reserved" are retained in Python alone or in any derivative 00019 # version prepared by Licensee. 00020 # 00021 # 3. In the event Licensee prepares a derivative work that is based on 00022 # or incorporates Python or any part thereof, and wants to make 00023 # the derivative work available to others as provided herein, then 00024 # Licensee hereby agrees to include in any such work a brief summary of 00025 # the changes made to Python. 00026 # 00027 # 4. PSF is making Python available to Licensee on an "AS IS" 00028 # basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR 00029 # IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND 00030 # DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS 00031 # FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT 00032 # INFRINGE ANY THIRD PARTY RIGHTS. 00033 # 00034 # 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 00035 # FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS 00036 # A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, 00037 # OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 00038 # 00039 # 6. This License Agreement will automatically terminate upon a material 00040 # breach of its terms and conditions. 00041 # 00042 # 7. Nothing in this License Agreement shall be deemed to create any 00043 # relationship of agency, partnership, or joint venture between PSF and 00044 # Licensee. This License Agreement does not grant permission to use PSF 00045 # trademarks or trade name in a trademark sense to endorse or promote 00046 # products or services of Licensee, or any third party. 00047 # 00048 # 8. By copying, installing or otherwise using Python, Licensee 00049 # agrees to be bound by the terms and conditions of this License 00050 # Agreement. 00051 00052 00053 def curry(_curried_func, *args, **kwargs): 00054 def _curried(*moreargs, **morekwargs): 00055 return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs)) 00056 return _curried 00057 00058 ### Begin from Python 2.5 functools.py ######################################## 00059 00060 # Summary of changes made to the Python 2.5 code below: 00061 # * swapped ``partial`` for ``curry`` to maintain backwards-compatibility 00062 # in Django. 00063 # * Wrapped the ``setattr`` call in ``update_wrapper`` with a try-except 00064 # block to make it compatible with Python 2.3, which doesn't allow 00065 # assigning to ``__name__``. 00066 00067 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation. 00068 # All Rights Reserved. 00069 00070 ############################################################################### 00071 00072 # update_wrapper() and wraps() are tools to help write 00073 # wrapper functions that can handle naive introspection 00074 00075 WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__') 00076 WRAPPER_UPDATES = ('__dict__',) 00077 def update_wrapper(wrapper, 00078 wrapped, 00079 assigned = WRAPPER_ASSIGNMENTS, 00080 updated = WRAPPER_UPDATES): 00081 """Update a wrapper function to look like the wrapped function 00082 00083 wrapper is the function to be updated 00084 wrapped is the original function 00085 assigned is a tuple naming the attributes assigned directly 00086 from the wrapped function to the wrapper function (defaults to 00087 functools.WRAPPER_ASSIGNMENTS) 00088 updated is a tuple naming the attributes off the wrapper that 00089 are updated with the corresponding attribute from the wrapped 00090 function (defaults to functools.WRAPPER_UPDATES) 00091 """ 00092 for attr in assigned: 00093 try: 00094 setattr(wrapper, attr, getattr(wrapped, attr)) 00095 except TypeError: # Python 2.3 doesn't allow assigning to __name__. 00096 pass 00097 for attr in updated: 00098 getattr(wrapper, attr).update(getattr(wrapped, attr)) 00099 # Return the wrapper so this can be used as a decorator via curry() 00100 return wrapper 00101 00102 def wraps(wrapped, 00103 assigned = WRAPPER_ASSIGNMENTS, 00104 updated = WRAPPER_UPDATES): 00105 """Decorator factory to apply update_wrapper() to a wrapper function 00106 00107 Returns a decorator that invokes update_wrapper() with the decorated 00108 function as the wrapper argument and the arguments to wraps() as the 00109 remaining arguments. Default arguments are as for update_wrapper(). 00110 This is a convenience function to simplify applying curry() to 00111 update_wrapper(). 00112 """ 00113 return curry(update_wrapper, wrapped=wrapped, 00114 assigned=assigned, updated=updated) 00115 00116 ### End from Python 2.5 functools.py ##########################################