Repository: pydantic/pydantic

Issue:
lenient_issubclass does not work for generic aliases
### Checks

* [x] I added a descriptive title to this issue
* [x] I have searched (google, github) for similar issues and couldn't find anything
* [x] I have read and followed [the docs](https://pydantic-docs.helpmanual.io/) and still think this is a bug

# Bug

Output of `python -c "import pydantic.utils; print(pydantic.utils.version_info())"`:
```
             pydantic version: 1.7.3
            pydantic compiled: False
                 install path: /home/user/pydantic/pydantic
               python version: 3.9.0 (default, Nov 15 2020, 14:28:56)  [GCC 7.3.0]
                     platform: Linux-5.4.0-65-generic-x86_64-with-glibc2.31
     optional deps. installed: ['devtools', 'dotenv', 'email-validator', 'typing-extensions']
```

Using `lenient_issubclass` breaks for `GernicAlias` types.
This is important in python >= 3.9 as the typing become the default for defining types.


Reproducible example:

```py
from pydantic.utils import lenient_issubclass
from collections.abc import Mapping
# should not raise an error here:
assert lenient_issubclass(list[str], Mapping) is False
```

raises:
```
    if lenient_issubclass(param.annotation, Request):
    \lib\site-packages\pydantic\utils.py:151: in lenient_issubclass
    return isinstance(cls, type) and issubclass(cls, class_or_tuple)
    \lib\abc.py:102: in __subclasscheck__
    return _abc_subclasscheck(cls, subclass)
E   TypeError: issubclass() arg 1 must be a class
```




Discussion:

Resolving patch:
diff --git a/pydantic/typing.py b/pydantic/typing.py
--- a/pydantic/typing.py
+++ b/pydantic/typing.py
@@ -221,6 +221,7 @@ def get_args(tp: Type[Any]) -> Tuple[Any, ...]:
     'CallableGenerator',
     'ReprArgs',
     'CallableGenerator',
+    'GenericAlias',
     'get_args',
     'get_origin',
     'typing_base',
diff --git a/pydantic/utils.py b/pydantic/utils.py
--- a/pydantic/utils.py
+++ b/pydantic/utils.py
@@ -24,7 +24,7 @@
     no_type_check,
 )
 
-from .typing import NoneType, display_as_type
+from .typing import GenericAlias, NoneType, display_as_type
 from .version import version_info
 
 if TYPE_CHECKING:
@@ -149,7 +149,12 @@ def validate_field_name(bases: List[Type['BaseModel']], field_name: str) -> None
 
 
 def lenient_issubclass(cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...]]) -> bool:
-    return isinstance(cls, type) and issubclass(cls, class_or_tuple)
+    try:
+        return isinstance(cls, type) and issubclass(cls, class_or_tuple)
+    except TypeError:
+        if isinstance(cls, GenericAlias):
+            return False
+        raise  # pragma: no cover
 
 
 def in_ipython() -> bool:


Test patch:
diff --git a/tests/test_utils.py b/tests/test_utils.py
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -109,6 +109,14 @@ class A(str):
     assert lenient_issubclass(A, str) is True
 
 
+@pytest.mark.skipif(sys.version_info < (3, 9), reason='generic aliases are not available in python < 3.9')
+def test_lenient_issubclass_with_generic_aliases():
+    from collections.abc import Mapping
+
+    # should not raise an error here:
+    assert lenient_issubclass(list[str], Mapping) is False
+
+
 def test_lenient_issubclass_is_lenient():
     assert lenient_issubclass('a', 'a') is False