def call_func()

in src/dubbo/utils.py [0:0]


    def call_func(func: Callable, args_and_kwargs: Any = None) -> Any:
        """
        Call the function with the given arguments and keyword arguments.

        :param func:
            The callable function.
        :type func: Callable
        :param args_and_kwargs:
            The arguments and keyword arguments.

            the provided values must follow these forms:
            - No arguments required, pass -> None
            - Multiple positional arguments -> Tuple (e.g., ((1, 2),{}))
            - Multiple keyword arguments -> Dict (e.g., ((),{"a": 1, "b": 2}))
            - Both positional and keyword arguments -> Tuple of length 2
                (e.g., ((1, 2), {"a": 1, "b": 2}))

        :type args_and_kwargs: Tuple
        :return: The result of the function.
        :rtype: Any
        """

        # split the arguments and keyword arguments
        if isinstance(args_and_kwargs, tuple) and len(args_and_kwargs) == 2:
            args, kwargs = args_and_kwargs
        else:
            raise ValueError(
                "Invalid function arguments, the provided values must follow these forms:"
                "1.No arguments required, pass -> None"
                "2.Multiple positional arguments -> Tuple (e.g., ((1, 2),{}))"
                "3.Multiple keyword arguments -> Dict (e.g., ((),{'a': 1, 'b': 2}))"
                "4.Both positional and keyword arguments -> Tuple of length 2"
                " (e.g., ((1, 2), {'a': 1, 'b': 2}))"
            )

        # If the function is not callable, try to call the function directly
        try:
            if not FunctionHelper.is_callable(func):
                return func(*args, **kwargs)
        except Exception as e:
            raise e

        # Get the function signature
        sig = inspect.signature(func)

        # Get the function parameters and check if the function supports *args and **kwargs
        params = sig.parameters
        param_kinds = [p.kind for p in params.values()]
        has_var_positional = inspect.Parameter.VAR_POSITIONAL in param_kinds
        has_var_keyword = inspect.Parameter.VAR_KEYWORD in param_kinds

        # If the function has no arguments or only one argument, call the function directly
        if len(params) == 0 or args_and_kwargs is None:
            return func()

        # If the function accepts both *args and **kwargs
        if has_var_positional and has_var_keyword:
            return func(*args, **kwargs)

        # If the function supports *args but not **kwargs
        if has_var_positional:
            return func(*args)

        # If the function supports **kwargs but not *args
        if has_var_keyword:
            return func(**kwargs)

        # common case
        bound_args = sig.bind(*args, **kwargs)
        bound_args.apply_defaults()
        return func(*bound_args.args, **bound_args.kwargs)