Repository: gradio-app/gradio

Issue:
"issubclass() arg 1 must be a class" error appears when using input parameters with Optional type hint
### Describe the bug

I'm getting an error `issubclass() arg 1 must be a class` when using Optional typing in the target function. The problem started appearing with version `3.21.0`

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Reproduction

Steps to reproduce:
1. Install gradio `3.21.0`
2. Target function with the following type hints:
```
def transcribe(
        language: Optional[str] = 'auto',
):
```
3. Run gradio application

AR:
```
  File ".../app.py", line 67, in <module>
    allow_flagging='never',
  File ".../.venv/lib/python3.7/site-packages/gradio/interface.py", line 463, in __init__
    self.attach_submit_events(submit_btn, stop_btn)
  File ".../.venv/lib/python3.7/site-packages/gradio/interface.py", line 624, in attach_submit_events
    postprocess=not (self.api_mode),
  File ".../.venv/lib/python3.7/site-packages/gradio/events.py", line 147, in __call__
    trigger_only_on_success=self.trigger_only_on_success,
  File ".../.venv/lib/python3.7/site-packages/gradio/blocks.py", line 190, in set_event_trigger
    check_function_inputs_match(fn, inputs, inputs_as_dict)
  File ".../.venv/lib/python3.7/site-packages/gradio/utils.py", line 943, in check_function_inputs_match
    if not is_special_typed_parameter(name):
  File ".../.venv/lib/python3.7/site-packages/gradio/utils.py", line 932, in is_special_typed_parameter
    is_event_data = issubclass(parameter_types.get(name, int), EventData)
TypeError: issubclass() arg 1 must be a class
```

The problem is that the first parameter for `issubclass` is `typing.Union[str, NoneType]`

### Screenshot

_No response_

### Logs

_Stacktrace is attached in the reproduction steps._


### System Info

```shell
Gradio 3.21.0, Python 3.7
```


### Severity

serious, but I can work around it by removing annotations 


Discussion:
@hnsywangxin , I didn't try to downgrade the version. The simpler way was to remove type annotations. 
> @hnsywangxin , I didn't try to downgrade the version. The simpler way was to remove type annotations.

Same, removing the annotations solved.
I'm having the same problem. It is a more generic problem than you described.

For me it happens with the following code:

```
def from_raw(raw_pdf: Union[str, bytes]) -> str:
...

pdf_file.upload(from_raw, inputs=[file], outputs=[text])
```

It seems like gradio events can not handle type annotations with the `fn` arguments.

This should be fixed.
This issue has not been resolved. On Gradio 3.28 it still occurs, and removing the type annotations still seems to be the only resolution. 
annoying
thanks for your advice, removing type annotations fixed it for me too
Will take a look and get a fix out this week!

Resolving patch:
diff --git a/gradio/utils.py b/gradio/utils.py
--- a/gradio/utils.py
+++ b/gradio/utils.py
@@ -41,12 +41,12 @@
 import matplotlib
 import requests
 from markdown_it import MarkdownIt
-from pygments import highlight
-from pygments.formatters import HtmlFormatter
-from pygments.lexers import get_lexer_by_name
 from mdit_py_plugins.dollarmath.index import dollarmath_plugin
 from mdit_py_plugins.footnote.index import footnote_plugin
 from pydantic import BaseModel, parse_obj_as
+from pygments import highlight
+from pygments.formatters import HtmlFormatter
+from pygments.lexers import get_lexer_by_name
 
 import gradio
 from gradio.context import Context
@@ -845,22 +845,25 @@ def get_type_hints(fn):
     return {}
 
 
+def is_special_typed_parameter(name, parameter_types):
+    from gradio.helpers import EventData
+    from gradio.routes import Request
+
+    """Checks if parameter has a type hint designating it as a gr.Request or gr.EventData"""
+    hint = parameter_types.get(name)
+    if not hint:
+        return False
+    is_request = hint == Request
+    is_event_data = inspect.isclass(hint) and issubclass(hint, EventData)
+    return is_request or is_event_data
+
+
 def check_function_inputs_match(fn: Callable, inputs: List, inputs_as_dict: bool):
     """
     Checks if the input component set matches the function
     Returns: None if valid, a string error message if mismatch
     """
 
-    def is_special_typed_parameter(name):
-        from gradio.helpers import EventData
-        from gradio.routes import Request
-
-        """Checks if parameter has a type hint designating it as a gr.Request or gr.EventData"""
-        is_request = parameter_types.get(name, "") == Request
-        # use int in the fall-back as that will always be false
-        is_event_data = issubclass(parameter_types.get(name, int), EventData)
-        return is_request or is_event_data
-
     signature = inspect.signature(fn)
     parameter_types = get_type_hints(fn)
     min_args = 0
@@ -869,7 +872,7 @@ def is_special_typed_parameter(name):
     for name, param in signature.parameters.items():
         has_default = param.default != param.empty
         if param.kind in [param.POSITIONAL_ONLY, param.POSITIONAL_OR_KEYWORD]:
-            if not is_special_typed_parameter(name):
+            if not is_special_typed_parameter(name, parameter_types):
                 if not has_default:
                     min_args += 1
                 max_args += 1


Test patch:
diff --git a/test/test_utils.py b/test/test_utils.py
--- a/test/test_utils.py
+++ b/test/test_utils.py
@@ -5,6 +5,7 @@
 import sys
 import unittest.mock as mock
 import warnings
+from typing import List
 from unittest.mock import MagicMock
 
 import pytest
@@ -14,7 +15,7 @@
 from pydantic import BaseModel
 from typing_extensions import Literal
 
-from gradio import EventData
+from gradio import EventData, Request
 from gradio.context import Context
 from gradio.test_data.blocks_configs import (
     XRAY_CONFIG,
@@ -34,6 +35,7 @@
     get_local_ip_address,
     get_type_hints,
     ipython_check,
+    is_special_typed_parameter,
     kaggle_check,
     launch_analytics,
     readme_to_html,
@@ -633,6 +635,16 @@ class GenericObject:
 
         assert len(get_type_hints(GenericObject())) == 0
 
+    def test_is_special_typed_parameter(self):
+        def func(a: List[str], b: Literal["a", "b"], c, d: Request):
+            pass
+
+        hints = get_type_hints(func)
+        assert not is_special_typed_parameter("a", hints)
+        assert not is_special_typed_parameter("b", hints)
+        assert not is_special_typed_parameter("c", hints)
+        assert is_special_typed_parameter("d", hints)
+
 
 class TestCheckFunctionInputsMatch:
     def test_check_function_inputs_match(self):