API reference¶
In general, using help(symbol) is the recommended way to get the latest documentation. In addition, this page provides an overview of the various elements in this package.
Main symbols¶
create_function¶
def create_function(func_signature: Union[str, Signature],
func_impl: Callable[[Any], Any],
func_name: str = None,
inject_as_first_arg: bool = False,
add_source: bool = True,
add_impl: bool = True,
doc: str = None,
qualname: str = None,
co_name: str = None,
module_name: str = None,
**attrs):
Creates a function with signature func_signature that will call func_impl when called. All arguments received by the generated function will be propagated as keyword-arguments to func_impl when it is possible (so all the time, except for var-positional or positional-only arguments that get passed as *args. Note that positional-only does not yet exist in python but this case is already covered because it is supported by Signature objects).
func_signature can be provided in different formats:
-
as a string containing the name and signature without 'def' keyword, such as
'foo(a, b: int, *args, **kwargs)'. In which case the name in the string will be used for the__name__and__qualname__of the created function by default. -
as a
Signatureobject, for example created usingsignature(f)or handcrafted. Since aSignatureobject does not contain any name, in this case the__name__and__qualname__of the created function will be copied fromfunc_implby default.
All the other metadata of the created function are defined as follows:
- default
__name__attribute (see above) can be overridden by providing a non-Nonefunc_name - default
__qualname__attribute (see above) can be overridden by providing a non-Nonequalname __annotations__attribute is created to match the annotations in the signature.__doc__attribute is copied fromfunc_impl.__doc__except if overridden usingdoc__module__attribute is copied fromfunc_impl.__module__except if overridden usingmodule_name__code__.co_name(see above) defaults to the same value as the above__name__attribute, except when that value is not a valid Python identifier, in which case it will be<lambda>. It can be overridden by providing aco_namethat is either a valid Python identifier or<lambda>.
Finally two new attributes are optionally created
__source__attribute: set ifadd_sourceisTrue(default), this attribute contains the source code of the generated function__func_impl__attribute: set ifadd_implisTrue(default), this attribute contains a pointer tofunc_impl
A lambda function will be created in the following cases:
- when
func_signatureis aSignatureobject andfunc_implis itself a lambda function, - when the function name, either derived from a
func_signaturestring, or given explicitly withfunc_name, is not a valid Python identifier, or - when the provided
co_nameis<lambda>.
Parameters:
-
func_signature: either a string without 'def' such as "foo(a, b: int, args, *kwargs)" or "(a, b: int)", or aSignatureobject, for example from the output ofinspect.signatureor from thefuncsigs.signaturebackport. Note that these objects can be created manually too. If the signature is provided as a string and contains a non-empty name, this name will be used instead of the one of the decorated function. -
func_impl: the function that will be called when the generated function is executed. Its signature should be compliant with (=more generic than)func_signature -
inject_as_first_arg: ifTrue, the created function will be injected as the first positional argument offunc_impl. This can be handy in case the implementation is shared between several facades and needs to know from which context it was called. Default=False -
func_name: provide a non-Nonevalue to override the created function__name__and__qualname__. If this isNone(default), the__name__will default to the one offunc_impliffunc_signatureis aSignature, or to the name defined infunc_signatureiffunc_signatureis astrand contains a non-empty name. -
add_source: a boolean indicating if a 'source' annotation should be added to the generated function (default: True) -
add_impl: a boolean indicating if a 'func_impl' annotation should be added to the generated function (default: True) -
doc: a string representing the docstring that will be used to set the doc attribute on the generated function. If None (default), the doc of func_impl will be used. -
qualname: a string representing the qualified name to be used. If None (default), the__qualname__will default to the one offunc_impliffunc_signatureis aSignature, or to the name defined infunc_signatureiffunc_signatureis astrand contains a non-empty name. -
co_name: a string representing the name to be used in the compiled code of the function. If None (default), the__code__.co_namewill default to the one offunc_impliffunc_signatureis aSignature, or to the name defined infunc_signatureiffunc_signatureis astrand contains a non-empty name. -
module_name: the name of the module to be set on the function (under module ). If None (default),func_impl.__module__will be used. -
attrs: other keyword attributes that should be set on the function. Note thatfunc_impl.__dict__is not automatically copied.
@with_signature¶
def with_signature(func_signature: Union[str, Signature],
func_name: str = None,
inject_as_first_arg: bool = False,
add_source: bool = True,
add_impl: bool = True,
doc: str = None,
qualname: str = None,
co_name: str = None,
module_name: str = None,
**attrs
):
A decorator for functions, to change their signature. The new signature should be compliant with the old one.
@with_signature(<arguments>)
def impl(...):
...
is totally equivalent to impl = create_function(<arguments>, func_impl=impl) except for one additional behaviour:
-
If
func_signatureis set toNone, there is noTypeErroras in create_function. Instead, this simply applies the new metadata (name, doc, module_name, attrs) to the decorated function without creating a wrapper.add_source,add_implandinject_as_first_argshould not be set in this case. -
func_signature: the new signature of the decorated function. Either a string without 'def' such as "foo(a, b: int, args, *kwargs)" or "(a, b: int)", or aSignatureobject, for example from the output ofinspect.signatureor from thefuncsigs.signaturebackport. Note that these objects can be created manually too. If the signature is provided as a string and contains a non-empty name, this name will be used instead of the one of the decorated function. FinallyNonecan be provided to indicate that user wants to only change the medatadata (func_name, doc, module_name, attrs) of the decorated function, without generating a new function. -
inject_as_first_arg: ifTrue, the created function will be injected as the first positional argument offunc_impl. This can be handy in case the implementation is shared between several facades and needs to know from which context it was called. Default=False -
func_name: provide a non-Nonevalue to override the created function__name__and__qualname__. If this isNone(default), the__name__will default to the one offunc_impliffunc_signatureis aSignature, or to the name defined infunc_signatureiffunc_signatureis astrand contains a non-empty name. -
add_source: a boolean indicating if a 'source' annotation should be added to the generated function (default: True) -
add_impl: a boolean indicating if a 'func_impl' annotation should be added to the generated function (default: True) -
doc: a string representing the docstring that will be used to set the doc attribute on the generated function. If None (default), the doc of the decorated function will be used. -
qualname: a string representing the qualified name to be used. If None (default), the__qualname__will default to the one offunc_impliffunc_signatureis aSignature, or to the name defined infunc_signatureiffunc_signatureis astrand contains a non-empty name. -
co_name: a string representing the name to be used in the compiled code of the function. If None (default), the__code__.co_namewill default to the one offunc_impliffunc_signatureis aSignature, or to the name defined infunc_signatureiffunc_signatureis astrand contains a non-empty name. -
module_name: the name of the module to be set on the function (under module ). If None (default), the__module__attribute of the decorated function will be used. -
attrs: other keyword attributes that should be set on the function. Note that the full__dict__of the decorated function is not automatically copied.
@wraps¶
def wraps(f,
new_sig: Union[str, Signature] = None,
prepend_args: Union[str, Parameter, Iterable[Union[str, Parameter]]] = None,
append_args: Union[str, Parameter, Iterable[Union[str, Parameter]]] = None,
remove_args: Union[str, Iterable[str]] = None,
func_name: str = None,
inject_as_first_arg: bool = False,
add_source: bool = True,
add_impl: bool = True,
doc: str = None,
qualname: str = None,
co_name: str = None,
module_name: str = None,
**attrs
):
A decorator to create a signature-preserving wrapper function.
It is similar to functools.wraps, but
-
relies on a proper dynamically-generated function. Therefore as opposed to
functools.wraps,- the wrapper body will not be executed if the arguments provided are not compliant with the signature - instead a
TypeErrorwill be raised before entering the wrapper body. - the arguments will always be received as keywords by the wrapper, when possible. See documentation for details.
- the wrapper body will not be executed if the arguments provided are not compliant with the signature - instead a
-
you can modify the signature of the resulting function, by providing a new one with
new_sigor by providing a list of arguments to remove inremove_args, to prepend inprepend_args, or to append inappend_args. See documentation on full and quick signature edits for details.
Comparison with @with_signature: @wraps(f) is equivalent to
`@with_signature(signature(f),
func_name=f.__name__,
doc=f.__doc__,
module_name=f.__module__,
qualname=f.__qualname__,
__wrapped__=f,
**f.__dict__,
**attrs)`
In other words, as opposed to @with_signature, the metadata (doc, module name, etc.) is provided by the wrapped wrapped_fun, so that the created function seems to be identical (except possiblyfor the signature). Note that all options in with_signature can still be overrided using parameters of @wraps.
The additional __wrapped__ attribute is added on the created function, to stay consistent with the functools.wraps behaviour. If the signature is modified through new_sig, remove_args, append_args or prepend_args, the __signature__ attribute will be added per PEP 362.
See also python documentation on @wraps
Parameters
-
wrapped_fun: the function that you intend to wrap with the decorated function. As infunctools.wraps,wrapped_funis used as the default reference for the exposed signature,__name__,__qualname__,__doc__and__dict__. -
new_sig: the new signature of the decorated function. By default it isNoneand means "same signature as inwrapped_fun" (similar behaviour as infunctools.wraps) If you wish to modify the exposed signature you can either useremove/prepend/append_args, or pass a non-Nonenew_sig. It can be either a string without 'def' such as "foo(a, b: int, args, *kwargs)" of "(a, b: int)", or aSignatureobject, for example from the output ofinspect.signatureor from thefuncsigs.signaturebackport. Note that these objects can be created manually too. If the signature is provided as a string and contains a non-empty name, this name will be used instead of the one ofwrapped_fun. -
prepend_args: a string or list of strings to prepend to the signature ofwrapped_fun. These extra arguments should not be passed towrapped_fun, as it does not know them. This is typically used to easily create a wrapper with additional arguments, without having to manipulate the signature objects. -
append_args: a string or list of strings to append to the signature ofwrapped_fun. These extra arguments should not be passed towrapped_fun, as it does not know them. This is typically used to easily create a wrapper with additional arguments, without having to manipulate the signature objects. -
remove_args: a string or list of strings to remove from the signature ofwrapped_fun. These arguments should be injected in the receivedkwargsbefore callingwrapped_fun, as it requires them. This is typically used to easily create a wrapper with less arguments, without having to manipulate the signature objects. -
func_name: provide a non-Nonevalue to override the created function__name__and__qualname__. If this isNone(default), the__name__will default to the ones ofwrapped_funifnew_sigisNoneor is aSignature, or to the name defined innew_sigifnew_sigis astrand contains a non-empty name. -
inject_as_first_arg: ifTrue, the created function will be injected as the first positional argument of the decorated function. This can be handy in case the implementation is shared between several facades and needs to know from which context it was called. Default=False -
add_source: a boolean indicating if a 'source' annotation should be added to the generated function (default: True) -
add_impl: a boolean indicating if a 'func_impl' annotation should be added to the generated function (default: True) -
doc: a string representing the docstring that will be used to set the doc attribute on the generated function. If None (default), the doc ofwrapped_funwill be used. Ifwrapped_funis an instance offunctools.partial, a special enhanced doc will be generated. -
qualname: a string representing the qualified name to be used. If None (default), the__qualname__will default to the one ofwrapped_fun, or the one innew_sigifnew_sigis provided as a string with a non-empty function name. -
co_name: a string representing the name to be used in the compiled code of the function. If None (default), the__code__.co_namewill default to the one offunc_impliffunc_signatureis aSignature, or to the name defined infunc_signatureiffunc_signatureis astrand contains a non-empty name. -
module_name: the name of the module to be set on the function (under module ). If None (default), the__module__attribute ofwrapped_funwill be used. -
attrs: other keyword attributes that should be set on the function. Note that the full__dict__ofwrapped_funis automatically copied.
create_wrapper¶
def create_wrapper(wrapped,
wrapper,
new_sig: Union[str, Signature] = None,
prepend_args: Union[str, Parameter, Iterable[Union[str, Parameter]]] = None,
append_args: Union[str, Parameter, Iterable[Union[str, Parameter]]] = None,
remove_args: Union[str, Iterable[str]] = None,
func_name: str = None,
inject_as_first_arg: bool = False,
add_source: bool = True,
add_impl: bool = True,
doc: str = None,
qualname: str = None,
co_name: str = None,
module_name: str = None,
**attrs
):
Creates a signature-preserving wrapper function. create_wrapper(wrapped, wrapper, **kwargs) is equivalent to wraps(wrapped, **kwargs)(wrapper). See @wraps
@partial¶
def partial(f: Callable,
*preset_pos_args,
**preset_kwargs
):
Equivalent of functools.partial but relies on a dynamically-created function. As a result the function
looks nicer to users in terms of apparent documentation, name, etc.
See documentation for details.
@with_partial¶
def with_partial(*preset_pos_args,
**preset_kwargs
):
Decorator to 'partialize' a function using partial.
Signature editing utils¶
add_signature_parameters¶
def add_signature_parameters(s, # type: Signature
first=(), # type: Union[str, Parameter, Iterable[Union[str, Parameter]]]
last=(), # type: Union[str, Parameter, Iterable[Union[str, Parameter]]]
custom=(), # type: Union[Parameter, Iterable[Parameter]]
custom_idx=-1 # type: int
):
Adds the provided parameters to the signature s (returns a new Signature instance).
s: the original signature to editfirst: a single element or a list ofParameterinstances to be added at the beginning of the parameter's list. Strings can also be provided, in which case the parameter kind will be created based on best guess.last: a single element or a list ofParameterinstances to be added at the end of the parameter's list. Strings can also be provided, in which case the parameter kind will be created based on best guess.custom: a single element or a list ofParameterinstances to be added at a custom position in the list. That position is determined withcustom_idxcustom_idx: the custom position to insert thecustomparameters to.
remove_signature_parameters¶
def remove_signature_parameters(s,
*param_names):
Removes the provided parameters from the signature s (returns a new Signature instance).