def get_type_hints(param, module):
    """Gets the type hints for a parameter."""

    def extract_args(
        arg,
        module_name_prefix,
        additional_interfaces,
        user_fn_refs: list[str],
        append=True,
        arg_of=None,
    ):
        """Recursively extracts the arguments from a type hint."""
        arg_names = []
        args = get_type_arguments(arg)

        # These are local classes that are used in types
        if inspect.isclass(arg) and arg.__module__.startswith(module_name_prefix):
            # get sourcecode for the class

            source_code = inspect.getsource(arg)
            source_code = format(
                re.sub(r"(\"\"\".*?\"\"\")", "", source_code, flags=re.DOTALL), "other"
            )

            if arg_of is not None:
                refs = get_deep(additional_interfaces, [arg_of, "refs"])

                if refs is None:
                    refs = [arg.__name__]
                elif isinstance(refs, list) and arg.__name__ not in refs:
                    refs.append(arg.__name__)

                set_deep(additional_interfaces, [arg_of, "refs"], refs)

            if get_deep(additional_interfaces, [arg.__name__, "source"]) is None:
                set_deep(additional_interfaces, [arg.__name__, "source"], source_code)

            for field_type in typing.get_type_hints(arg).values():
                # We want to recursively extract the source code for the fields but we don't want to add them to the list of arguments
                new_args = extract_args(
                    field_type,
                    module_name_prefix,
                    additional_interfaces,
                    user_fn_refs,
                    False,
                    arg.__name__,
                )

                if len(new_args) > 0:
                    arg_names.append(new_args)

            if append:
                arg_names.append(arg.__name__)
                if arg.__name__ not in user_fn_refs:
                    user_fn_refs.append(arg.__name__)
        elif len(args) > 0:
            if append:
                arg_names.append(get_container_name(arg))
            for inner_arg in list(args):
                new_args = extract_args(
                    inner_arg,
                    module_name_prefix,
                    additional_interfaces,
                    user_fn_refs,
                    append,
                    arg_of,
                )

                if len(new_args) > 0:
                    arg_names.append(new_args)
        else:  # noqa: PLR5501
            if append:
                arg_names.append(get_param_name(arg))
        return arg_names

    module_name_prefix = module.__name__ + "."
    additional_interfaces = {}
    user_fn_refs = []

    args = extract_args(
        param,
        module_name_prefix,
        additional_interfaces,
        user_fn_refs,
        True,
    )

    formatted_type = format_type(args)

    return (formatted_type, additional_interfaces, user_fn_refs)
Gets the type hints for a parameter.
gradio/cli/commands/components/_docs_utils.py