Funcgen¶
A small module for generating sets of function signatures and corresponding function objects.
Installation¶
funcgen
requires Python >= 3.6
because it relies on modern type annotations.
pip install funcgen
Example¶
>>> import funcgen
>>>
>>> def wrapper(present):
... log(f'Wrapped {present.__name__}')
... return present
...
>>> def test_wrapper():
... for funcs in funcgen.all_valid_functions():
... assert all(wrapper(f) == f for f in funcs)
...
>>> test_wrapper()
API¶
Contents¶
This will generate every combination of the parameters and parameter attributes passed to it, if that combination results in a valid Python function signature. |
|
A convenience function that will generate an example of every category of valid function signature for Python. |
|
For every signature in |
|
A convenience function that feeds |
|
Takes in parameter names, defaults, and annotations and generates every sequence of parameters possible from every combination of those attributes. |
Documentation¶
-
funcgen.
valid_signatures
(args: Sequence[Tuple[Sequence[str], Sequence[Any], Sequence[Type]]] = [], kwargs: Sequence[Tuple[Sequence[str], Sequence[Any], Sequence[Type]]] = [], var_args: Tuple[Sequence[str], Sequence[Type]] = ([], []), var_kwargs: Tuple[Sequence[str], Sequence[Type]] = ([], []), return_annotations: Sequence[object] = [<class 'inspect._empty'>]) → Generator[inspect.Signature, None, None][source]¶ This will generate every combination of the parameters and parameter attributes passed to it, if that combination results in a valid Python function signature.
A
VarParamTuple
describes the range of attributes to give a variadic parameter. It is a tuple of two sequences: names and type annotations, respectively. The cross product of that tuple represents the range of attributes to give that parameter in the results.Use
Parameter.empty
to specify a missing type annotation or default value, andSignature.empty
to specify a missing return type annotation.>>> args = [(['arg1'], [Parameter.empty, 42], [int])] >>> kwargs = [] >>> var_args = (['args'], [float]) >>> var_kwargs = ([], []) >>> return_annotations = [Signature.empty, int] >>> [str(s) for s in valid_signatures(args, kwargs, var_args, var_kwargs, return_annotations)] ['()', '() -> int', '(*args:float)', '(*args:float) -> int', '(arg1:int)', '(arg1:int) -> int', '(arg1:int, *args:float)', '(arg1:int, *args:float) -> int', '(arg1:int=42)', '(arg1:int=42) -> int', '(arg1:int=42, *args:float)', '(arg1:int=42, *args:float) -> int']
- Parameters
args (Sequence[ParamTuple]) – A sequence of
ParamTuples
used to createParameter.POSITIONAL_OR_KEYWORD
Parameters
(seevalid_parameters
)kwargs (Sequence[ParamTuple]) – A sequence of
ParamTuples
used to createParameter.KEYWORD_ONLY
Parameters
(seevalid_parameters
)var_args (Sequence[VarParamTuple]) – A sequence of
VarParamTuples
used to createParameter.VAR_POSITIONAL
Parameters
(see above)var_kwargs (Sequence[VarParamTuple]) – A sequence of
VarParamTuples
used to createParameter.VAR_KEYWORD
Parameters
(see above)return_annotations – A sequence of return annotations.
-
funcgen.
all_valid_signatures
() → Generator[inspect.Signature, None, None][source]¶ A convenience function that will generate an example of every category of valid function signature for Python. That is all combinations of
Zero, one, and two positional parameters with and without type annotations and default values.
Zero, one, and two keyword only parameters with and without type annotations and default values.
With and without *args, with and without a type annotation.
With and without **kwargs, with and without a type annotation.
With and without a return type annotation.
See the source for the call to
valid_signatures
-
funcgen.
valid_functions
(signatures: Iterable[inspect.Signature]) → Generator[Sequence[Callable], None, None][source]¶ For every signature in
signatures
this function will yield a sequence of callable objects representing various forms that signature could take.Given an example signature like:
(arg1:int=42, *args:str, kwarg1=False, kwarg2:bool) -> bytes
The sequence yielded is equivalent to this:
# Regular function def f(arg1:int=42, *args:str, kwarg1=False, kwarg2:bool) -> bytes: pass # Bound Method class Foo: def f(arg1:int=42, *args:str, kwarg1=False, kwarg2:bool) -> bytes: pass # Static Class Method class FooStatic: @staticmethod def f(arg1:int=42, *args:str, kwarg1=False, kwarg2:bool) -> bytes: pass # Sequence yielded return f, Foo().f, FooStatic.f, FooStatic().f
- Parameters
signatures –
-
funcgen.
all_valid_functions
() → Generator[Sequence[Callable], None, None][source]¶ A convenience function that feeds
all_valid_signatures
intovalid_functions
to produce all callable forms of all valid signatures.
-
funcgen.
valid_parameters
(param_kind: inspect._ParameterKind, params: Sequence[Tuple[Sequence[str], Sequence[Any], Sequence[Type]]]) → Generator[List[inspect.Parameter], None, None][source]¶ Takes in parameter names, defaults, and annotations and generates every sequence of parameters possible from every combination of those attributes.
A
ParamTuple
is a tuple of three sequences: names, default values, and annotations, respectively.params
is a sequence ofParamTuples
such that the cross product ofparams[i]
represents the range of desired values for the ith parameter.Given every subset
params[:i]
fori
inrange(len(params))
, this function will yield items from the cross product of the desired values for those parameters in the subset as a list ofParameters
.If
param_kind
isParameter.POSITIONAL_OR_KEYWORD
orParameter.POSITIONAL_ONLY
, then those lists where some parameter has a default value and previous parameter does not are not yielded because they would be invalid.Use
Parameter.empty
to specify the abscence of type annotation or default value.>>> [str(x) for x in valid_parameters(Parameter.POSITIONAL_OR_KEYWORD, ... [(['arg1'], ... [42, Parameter.empty], ... [int, Parameter.empty])])] ['[]', '[<Parameter "arg1:int=42">]', '[<Parameter "arg1=42">]', '[<Parameter "arg1:int">]', '[<Parameter "arg1">]']
>>> [str(x) for x in valid_parameters(Parameter.POSITIONAL_OR_KEYWORD, ... [(['arg1'], [42, Parameter.empty], [int]), ... (['arg2'], [107.7, Parameter.empty], [float])])] ['[]', '[<Parameter "arg1:int=42">]', '[<Parameter "arg1:int">]', '[<Parameter "arg1:int=42">, <Parameter "arg2:float=107.7">]', '[<Parameter "arg1:int">, <Parameter "arg2:float=107.7">]', '[<Parameter "arg1:int">, <Parameter "arg2:float">]']
>>> [str(x) for x in valid_parameters(Parameter.KEYWORD_ONLY, ... [(['arg1'], [42, Parameter.empty], [int]), ... (['arg2'], [107.7, Parameter.empty], [float])])] ['[]', '[<Parameter "arg1:int=42">]', '[<Parameter "arg1:int">]', '[<Parameter "arg1:int=42">, <Parameter "arg2:float=107.7">]', '[<Parameter "arg1:int">, <Parameter "arg2:float=107.7">]', '[<Parameter "arg1:int=42">, <Parameter "arg2:float">]', '[<Parameter "arg1:int">, <Parameter "arg2:float">]']
- Parameters
param_kind – must be
Parameter.POSITIONAL_ONLY
,Parameter.KEYWORD_ONLY
, orParameter.POSITIONAL_OR_KEYWORD
.params (Sequence[ParamTuple]) –