funcutils
- functools
fixes¶
Python’s built-in functools
module builds several useful
utilities on top of Python’s first-class function
support. funcutils
generally stays in the same vein, adding to and
correcting Python’s standard metaprogramming facilities.
Decoration¶
Decorators are among Python’s most elegant and succinct language features, and boltons adds one special function to make them even more powerful.
-
boltons.funcutils.
wraps
(func, injected=None, **kw)[source]¶ Modeled after the built-in
functools.wraps()
, this function is used to make your decorator’s wrapper functions reflect the wrapped function’s:- Name
- Documentation
- Module
- Signature
The built-in
functools.wraps()
copies the first three, but does not copy the signature. This version ofwraps
can copy the inner function’s signature exactly, allowing seamless usage andintrospection
. Usage is identical to the built-in version:>>> from boltons.funcutils import wraps >>> >>> def print_return(func): ... @wraps(func) ... def wrapper(*args, **kwargs): ... ret = func(*args, **kwargs) ... print(ret) ... return ret ... return wrapper ... >>> @print_return ... def example(): ... '''docstring''' ... return 'example return value' >>> >>> val = example() example return value >>> example.__name__ 'example' >>> example.__doc__ 'docstring'
In addition, the boltons version of wraps supports modifying the outer signature based on the inner signature. By passing a list of injected argument names, those arguments will be removed from the outer wrapper’s signature, allowing your decorator to provide arguments that aren’t passed in.
Parameters: - func (function) – The callable whose attributes are to be copied.
- injected (list) – An optional list of argument names which should not appear in the new wrapper’s signature.
- update_dict (bool) – Whether to copy other, non-standard attributes of func over to the wrapper. Defaults to True.
- inject_to_varkw (bool) – Ignore missing arguments when a
**kwargs
-type catch-all is present. Defaults to True.
For more in-depth wrapping of functions, see the
FunctionBuilder
type, on which wraps was built.
Function construction¶
Functions are so key to programming in Python that there will even arise times where Python functions must be constructed in Python. Thankfully, Python is a dynamic enough to make this possible. Boltons makes it easy.
-
class
boltons.funcutils.
FunctionBuilder
(name, **kw)[source]¶ The FunctionBuilder type provides an interface for programmatically creating new functions, either based on existing functions or from scratch.
Values are passed in at construction or set as attributes on the instance. For creating a new function based of an existing one, see the
from_func()
classmethod. At any point,get_func()
can be called to get a newly compiled function, based on the values configured.>>> fb = FunctionBuilder('return_five', doc='returns the integer 5', ... body='return 5') >>> f = fb.get_func() >>> f() 5 >>> fb.varkw = 'kw' >>> f_kw = fb.get_func() >>> f_kw(ignored_arg='ignored_val') 5
Note that function signatures themselves changed quite a bit in Python 3, so several arguments are only applicable to FunctionBuilder in Python 3. Except for name, all arguments to the constructor are keyword arguments.
Parameters: - name (str) – Name of the function.
- doc (str) – Docstring for the function, defaults to empty.
- module (str) – Name of the module from which this function was imported. Defaults to None.
- body (str) – String version of the code representing the body
of the function. Defaults to
'pass'
, which will result in a function which does nothing and returnsNone
. - args (list) – List of argument names, defaults to empty list, denoting no arguments.
- varargs (str) – Name of the catch-all variable for positional
arguments. E.g., “args” if the resultant function is to have
*args
in the signature. Defaults to None. - varkw (str) – Name of the catch-all variable for keyword
arguments. E.g., “kwargs” if the resultant function is to have
**kwargs
in the signature. Defaults to None. - defaults (dict) – A mapping of argument names to default values.
- kwonlyargs (list) – Argument names which are only valid as keyword arguments. Python 3 only.
- kwonlydefaults (dict) – A mapping, same as normal defaults, but only for the kwonlyargs. Python 3 only.
- annotations (dict) – Mapping of type hints and so forth. Python 3 only.
- filename (str) – The filename that will appear in tracebacks. Defaults to “boltons.funcutils.FunctionBuilder”.
- indent (int) – Number of spaces with which to indent the function body. Values less than 1 will result in an error.
- dict (dict) – Any other attributes which should be added to the functions compiled with this FunctionBuilder.
All of these arguments are also made available as attributes which can be mutated as necessary.
-
classmethod
from_func
(func)[source]¶ Create a new FunctionBuilder instance based on an existing function. The original function will not be stored or modified.
-
get_defaults_dict
()[source]¶ Get a dictionary of function arguments with defaults and the respective values.
-
get_func
(execdict=None, add_source=True, with_dict=True)[source]¶ Compile and return a new function based on the current values of the FunctionBuilder.
Parameters: - execdict (dict) – The dictionary representing the scope in which the compilation should take place. Defaults to an empty dict.
- add_source (bool) – Whether to add the source used to a
special
__source__
attribute on the resulting function. Defaults to True. - with_dict (bool) – Add any custom attributes, if applicable. Defaults to True.
To see an example of usage, see the implementation of
wraps()
.
Improved partial
¶
-
boltons.funcutils.
partial
¶
-
class
boltons.funcutils.
InstancePartial
[source]¶ functools.partial
is a huge convenience for anyone working with Python’s great first-class functions. It allows developers to curry arguments and incrementally create simpler callables for a variety of use cases.Unfortunately there’s one big gap in its usefulness: methods. Partials just don’t get bound as methods and automatically handed a reference to
self
. TheInstancePartial
type remedies this by inheriting fromfunctools.partial
and implementing the necessary descriptor protocol. There are no other differences in implementation or usage.CachedInstancePartial
, below, has the same ability, but is slightly more efficient.
-
class
boltons.funcutils.
CachedInstancePartial
[source]¶ The
CachedInstancePartial
is virtually the same asInstancePartial
, adding support for method-usage tofunctools.partial
, except that upon first access, it caches the bound method on the associated object, speeding it up for future accesses, and bringing the method call overhead to about the same as non-partial
methods.See the
InstancePartial
docstring for more details.
Miscellaneous metaprogramming¶
-
boltons.funcutils.
copy_function
(orig, copy_dict=True)[source]¶ Returns a shallow copy of the function, including code object, globals, closure, etc.
>>> func = lambda: func >>> func() is func True >>> func_copy = copy_function(func) >>> func_copy() is func True >>> func_copy is not func True
Parameters: - orig (function) – The function to be copied. Must be a function, not just any method or callable.
- copy_dict (bool) – Also copy any attributes set on the function
instance. Defaults to
True
.
-
boltons.funcutils.
dir_dict
(obj, raise_exc=False)[source]¶ Return a dictionary of attribute names to values for a given object. Unlike
obj.__dict__
, this function returns all attributes on the object, including ones on parent classes.
-
boltons.funcutils.
mro_items
(type_obj)[source]¶ Takes a type and returns an iterator over all class variables throughout the type hierarchy (respecting the MRO).
>>> sorted(set([k for k, v in mro_items(int) if not k.startswith('__') and 'bytes' not in k and not callable(v)])) ['denominator', 'imag', 'numerator', 'real']