I’ve written some code that inspects function signatures, and I would like to generate test cases for it. For this, I need to be able to construct objects that result in a given Signature
object when signature
is called on them. I want to avoid just eval
-ing spliced together strings for this. Is there some other method for generating functions or objects that behave like them with signature
?
Specifically, I have this code:
from inspect import signature, Parameter
from typing import Any, Callable, ValuesView
def passable(fun: Callable[..., Any], arg: str | int) -> bool:
if not callable(fun):
raise TypeError("Argument fun to passable() must be callable")
if isinstance(arg, str):
return kwarg_passable(fun, arg)
elif isinstance(arg, int):
return arg_passable(fun, arg)
else:
raise TypeError("Argument arg to passable() must be int or str")
def kwarg_passable(fun: Callable[..., Any], arg_key: str) -> bool:
assert callable(fun)
assert isinstance(arg_key, str)
params: ValuesView[Parameter] = signature(fun).parameters.values()
return any(
param.kind is Parameter.VAR_KEYWORD
or (
param.kind in [Parameter.KEYWORD_ONLY, Parameter.POSITIONAL_OR_KEYWORD]
and param.name == arg_key
)
for param in params
)
def arg_passable(fun: Callable[..., Any], arg_ix: int) -> bool:
assert callable(fun)
assert isinstance(arg_ix, int)
params: ValuesView[Parameter] = signature(fun).parameters.values()
return sum(
1
for param in params
if param.kind in [Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD]
) > arg_ix or any(param.kind is Parameter.VAR_POSITIONAL for param in params)
I want to test passable
on randomly generated dummy functions using Hypothesis.