Repository: gradio-app/gradio
File: gradio/utils.py (Python)

Code before:
            for key in obj2:
                if key not in obj1:
                    edits.append(("add", path + [key], obj2[key]))
            return edits

        edits.append(("replace", path, obj2))
        return edits

    return compare_objects(old, new)


def get_upload_folder() -> str:
    return os.environ.get("GRADIO_TEMP_DIR") or str(
        (Path(tempfile.gettempdir()) / "gradio").resolve()
    )


def get_function_params(func: Callable) -> list[tuple[str, bool, Any, Any]]:
    """
    Gets the parameters of a function as a list of tuples of the form (name, has_default, default_value, type_hint).
    Excludes *args and **kwargs, as well as args that are Gradio-specific, such as gr.Request, gr.EventData, gr.OAuthProfile, and gr.OAuthToken.
    """
    params_info = []
    try:
        signature = inspect.signature(func)
    except Exception:
        signature = inspect.Signature()
    type_hints = get_type_hints(func)
    for name, parameter in signature.parameters.items():
        if parameter.kind in (
            inspect.Parameter.VAR_POSITIONAL,
            inspect.Parameter.VAR_KEYWORD,
        ):
            break
        if is_special_typed_parameter(name, type_hints):
            continue
        if parameter.default is inspect.Parameter.empty:
            params_info.append((name, False, None, type_hints.get(name, None)))
        else:
            params_info.append(
                (name, True, parameter.default, type_hints.get(name, None))
            )
    return params_info


def get_return_types(func: Callable) -> list:
    return_hint = inspect.signature(func).return_annotation

    if return_hint in {inspect.Signature.empty, None, NoneType}:
        return []


Review comment (suggestion):
I think we can be more specific:
```suggestion
    except ValueError:
```

Code after:
            for key in obj2:
                if key not in obj1:
                    edits.append(("add", path + [key], obj2[key]))
            return edits

        edits.append(("replace", path, obj2))
        return edits

    return compare_objects(old, new)


def get_upload_folder() -> str:
    return os.environ.get("GRADIO_TEMP_DIR") or str(
        (Path(tempfile.gettempdir()) / "gradio").resolve()
    )


def get_function_params(func: Callable) -> list[tuple[str, bool, Any, Any]]:
    """
    Gets the parameters of a function as a list of tuples of the form (name, has_default, default_value, type_hint).
    Excludes *args and **kwargs, as well as args that are Gradio-specific, such as gr.Request, gr.EventData, gr.OAuthProfile, and gr.OAuthToken.
    """
    params_info = []
    try:
        signature = inspect.signature(func)
    except ValueError:
        signature = inspect.Signature()
    type_hints = get_type_hints(func)
    for name, parameter in signature.parameters.items():
        if parameter.kind in (
            inspect.Parameter.VAR_POSITIONAL,
            inspect.Parameter.VAR_KEYWORD,
        ):
            break
        if is_special_typed_parameter(name, type_hints):
            continue
        if parameter.default is inspect.Parameter.empty:
            params_info.append((name, False, None, type_hints.get(name, None)))
        else:
            params_info.append(
                (name, True, parameter.default, type_hints.get(name, None))
            )
    return params_info


def get_return_types(func: Callable) -> list:
    return_hint = inspect.signature(func).return_annotation

    if return_hint in {inspect.Signature.empty, None, NoneType}:
        return []