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
Signature
object, for example created usingsignature(f)
or handcrafted. Since aSignature
object does not contain any name, in this case the__name__
and__qualname__
of the created function will be copied fromfunc_impl
by 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_name
that is either a valid Python identifier or<lambda>
.
Finally two new attributes are optionally created
__source__
attribute: set ifadd_source
isTrue
(default), this attribute contains the source code of the generated function__func_impl__
attribute: set ifadd_impl
isTrue
(default), this attribute contains a pointer tofunc_impl
A lambda function will be created in the following cases:
- when
func_signature
is aSignature
object andfunc_impl
is itself a lambda function, - when the function name, either derived from a
func_signature
string, or given explicitly withfunc_name
, is not a valid Python identifier, or - when the provided
co_name
is<lambda>
.
Parameters:
-
func_signature
: either a string without 'def' such as "foo(a, b: int, args, *kwargs)" or "(a, b: int)", or aSignature
object, for example from the output ofinspect.signature
or from thefuncsigs.signature
backport. 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-None
value to override the created function__name__
and__qualname__
. If this isNone
(default), the__name__
will default to the one offunc_impl
iffunc_signature
is aSignature
, or to the name defined infunc_signature
iffunc_signature
is astr
and 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_impl
iffunc_signature
is aSignature
, or to the name defined infunc_signature
iffunc_signature
is astr
and 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_name
will default to the one offunc_impl
iffunc_signature
is aSignature
, or to the name defined infunc_signature
iffunc_signature
is astr
and 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_signature
is set toNone
, there is noTypeError
as 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_impl
andinject_as_first_arg
should 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 aSignature
object, for example from the output ofinspect.signature
or from thefuncsigs.signature
backport. 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. FinallyNone
can 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-None
value to override the created function__name__
and__qualname__
. If this isNone
(default), the__name__
will default to the one offunc_impl
iffunc_signature
is aSignature
, or to the name defined infunc_signature
iffunc_signature
is astr
and 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_impl
iffunc_signature
is aSignature
, or to the name defined infunc_signature
iffunc_signature
is astr
and 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_name
will default to the one offunc_impl
iffunc_signature
is aSignature
, or to the name defined infunc_signature
iffunc_signature
is astr
and 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
TypeError
will 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_sig
or 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_fun
is 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 isNone
and 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 aSignature
object, for example from the output ofinspect.signature
or from thefuncsigs.signature
backport. 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 receivedkwargs
before 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-None
value to override the created function__name__
and__qualname__
. If this isNone
(default), the__name__
will default to the ones ofwrapped_fun
ifnew_sig
isNone
or is aSignature
, or to the name defined innew_sig
ifnew_sig
is astr
and 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_fun
will be used. Ifwrapped_fun
is 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_sig
ifnew_sig
is 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_name
will default to the one offunc_impl
iffunc_signature
is aSignature
, or to the name defined infunc_signature
iffunc_signature
is astr
and 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_fun
will be used. -
attrs
: other keyword attributes that should be set on the function. Note that the full__dict__
ofwrapped_fun
is 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 ofParameter
instances 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 ofParameter
instances 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 ofParameter
instances to be added at a custom position in the list. That position is determined withcustom_idx
custom_idx
: the custom position to insert thecustom
parameters to.
remove_signature_parameters
¶
def remove_signature_parameters(s,
*param_names):
Removes the provided parameters from the signature s
(returns a new Signature
instance).