diff options
Diffstat (limited to 'Lib/functools.py')
| -rw-r--r-- | Lib/functools.py | 61 | 
1 files changed, 43 insertions, 18 deletions
diff --git a/Lib/functools.py b/Lib/functools.py index 4935c9f68e..8783f08488 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -1,26 +1,51 @@ -"""functools.py - Tools for working with functions +"""functools.py - Tools for working with functions and callable objects  """  # Python module wrapper for _functools C module  # to allow utilities written in Python to be added  # to the functools module.  # Written by Nick Coghlan <ncoghlan at gmail.com> -#   Copyright (c) 2006 Python Software Foundation. +#   Copyright (C) 2006 Python Software Foundation. +# See C source code for _functools credits/copyright  from _functools import partial -__all__ = [ -    "partial", -] -# Still to come here (need to write tests and docs): -#   update_wrapper - utility function to transfer basic function -#                    metadata to wrapper functions -#   WRAPPER_ASSIGNMENTS & WRAPPER_UPDATES - defaults args to above -#           (update_wrapper has been approved by BDFL) -#   wraps - decorator factory equivalent to: -#               def wraps(f): -#                     return partial(update_wrapper, wrapped=f) -# -# The wraps function makes it easy to avoid the bug that afflicts the -# decorator example in the python-dev email proposing the -# update_wrapper function: -# http://mail.python.org/pipermail/python-dev/2006-May/064775.html +# update_wrapper() and wraps() are tools to help write +# wrapper functions that can handle naive introspection + +WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__') +WRAPPER_UPDATES = ('__dict__',) +def update_wrapper(wrapper, +                   wrapped, +                   assigned = WRAPPER_ASSIGNMENTS, +                   updated = WRAPPER_UPDATES): +    """Update a wrapper function to look like the wrapped function + +       wrapper is the function to be updated +       wrapped is the original function +       assigned is a tuple naming the attributes assigned directly +       from the wrapped function to the wrapper function (defaults to +       functools.WRAPPER_ASSIGNMENTS) +       updated is a tuple naming the attributes off the wrapper that +       are updated with the corresponding attribute from the wrapped +       function (defaults to functools.WRAPPER_UPDATES) +    """ +    for attr in assigned: +        setattr(wrapper, attr, getattr(wrapped, attr)) +    for attr in updated: +        getattr(wrapper, attr).update(getattr(wrapped, attr)) +    # Return the wrapper so this can be used as a decorator via partial() +    return wrapper + +def wraps(wrapped, +          assigned = WRAPPER_ASSIGNMENTS, +          updated = WRAPPER_UPDATES): +    """Decorator factory to apply update_wrapper() to a wrapper function + +       Returns a decorator that invokes update_wrapper() with the decorated +       function as the wrapper argument and the arguments to wraps() as the +       remaining arguments. Default arguments are as for update_wrapper(). +       This is a convenience function to simplify applying partial() to +       update_wrapper(). +    """ +    return partial(update_wrapper, wrapped=wrapped, +                   assigned=assigned, updated=updated)  | 
