def check_callable(callable_: typing.Callable, hint: type) -> bool:
"""Check argument type & return type of :class:`typing.Callable`. since it
raises check :class:`typing.Callable` using `isinstance`, so compare in
diffrent way
:param callable_: callable object given as a argument
:param hint: assumed type of given ``callable_``
"""
if not callable(callable_):
return type(callable_), False
if callable(callable_) and not hasattr(callable_, '__code__'):
return type(callable_), True
hints = typing.get_type_hints(callable_)
return_type = hints.pop('return', type(None))
signature = inspect.signature(callable_)
arg_types = tuple(
param.annotation
for _, param in signature.parameters.items()
)
correct = all({
any({
hint.__args__ is None,
hint.__args__ is Ellipsis,
hint.__args__ == arg_types,
}),
any({
hint.__result__ is None,
hint.__result__ in (typing.Any, return_type)
})
})
return typing.Callable[list(arg_types), return_type], correct
评论列表
文章目录