| Nick Coghlan | 676725d | 2006-06-08 13:54:49 +0000 | [diff] [blame] | 1 | """functools.py - Tools for working with functions and callable objects | 
| Nick Coghlan | 0849014 | 2006-05-29 20:27:44 +0000 | [diff] [blame] | 2 | """ | 
 | 3 | # Python module wrapper for _functools C module | 
 | 4 | # to allow utilities written in Python to be added | 
 | 5 | # to the functools module. | 
 | 6 | # Written by Nick Coghlan <ncoghlan at gmail.com> | 
| Nick Coghlan | 676725d | 2006-06-08 13:54:49 +0000 | [diff] [blame] | 7 | #   Copyright (C) 2006 Python Software Foundation. | 
 | 8 | # See C source code for _functools credits/copyright | 
| Nick Coghlan | 0849014 | 2006-05-29 20:27:44 +0000 | [diff] [blame] | 9 |  | 
| Brett Cannon | 83e8184 | 2008-08-09 23:30:55 +0000 | [diff] [blame] | 10 | from _functools import partial, reduce | 
| Nick Coghlan | 0849014 | 2006-05-29 20:27:44 +0000 | [diff] [blame] | 11 |  | 
| Nick Coghlan | 676725d | 2006-06-08 13:54:49 +0000 | [diff] [blame] | 12 | # update_wrapper() and wraps() are tools to help write | 
 | 13 | # wrapper functions that can handle naive introspection | 
 | 14 |  | 
 | 15 | WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__') | 
 | 16 | WRAPPER_UPDATES = ('__dict__',) | 
 | 17 | def update_wrapper(wrapper, | 
 | 18 |                    wrapped, | 
 | 19 |                    assigned = WRAPPER_ASSIGNMENTS, | 
 | 20 |                    updated = WRAPPER_UPDATES): | 
 | 21 |     """Update a wrapper function to look like the wrapped function | 
 | 22 |  | 
 | 23 |        wrapper is the function to be updated | 
 | 24 |        wrapped is the original function | 
 | 25 |        assigned is a tuple naming the attributes assigned directly | 
 | 26 |        from the wrapped function to the wrapper function (defaults to | 
 | 27 |        functools.WRAPPER_ASSIGNMENTS) | 
| Andrew M. Kuchling | efb5707 | 2006-10-26 19:16:46 +0000 | [diff] [blame] | 28 |        updated is a tuple naming the attributes of the wrapper that | 
| Nick Coghlan | 676725d | 2006-06-08 13:54:49 +0000 | [diff] [blame] | 29 |        are updated with the corresponding attribute from the wrapped | 
 | 30 |        function (defaults to functools.WRAPPER_UPDATES) | 
 | 31 |     """ | 
 | 32 |     for attr in assigned: | 
 | 33 |         setattr(wrapper, attr, getattr(wrapped, attr)) | 
 | 34 |     for attr in updated: | 
| Andrew M. Kuchling | 41eb716 | 2006-10-27 16:39:10 +0000 | [diff] [blame] | 35 |         getattr(wrapper, attr).update(getattr(wrapped, attr, {})) | 
| Nick Coghlan | 676725d | 2006-06-08 13:54:49 +0000 | [diff] [blame] | 36 |     # Return the wrapper so this can be used as a decorator via partial() | 
 | 37 |     return wrapper | 
 | 38 |  | 
 | 39 | def wraps(wrapped, | 
 | 40 |           assigned = WRAPPER_ASSIGNMENTS, | 
 | 41 |           updated = WRAPPER_UPDATES): | 
 | 42 |     """Decorator factory to apply update_wrapper() to a wrapper function | 
 | 43 |  | 
 | 44 |        Returns a decorator that invokes update_wrapper() with the decorated | 
 | 45 |        function as the wrapper argument and the arguments to wraps() as the | 
 | 46 |        remaining arguments. Default arguments are as for update_wrapper(). | 
 | 47 |        This is a convenience function to simplify applying partial() to | 
 | 48 |        update_wrapper(). | 
 | 49 |     """ | 
 | 50 |     return partial(update_wrapper, wrapped=wrapped, | 
 | 51 |                    assigned=assigned, updated=updated) |