def is_generic_type(tp):
if NEW_TYPING:<EOL><INDENT>return (isinstance(tp, type) and issubclass(tp, Generic) or<EOL>isinstance(tp, _GenericAlias) and<EOL>tp.__origin__ not in (Union, tuple, ClassVar, collections.abc.Callable))<EOL><DEDENT>return (isinstance(tp, GenericMeta) and not<EOL>isinstance(tp, (CallableMeta, TupleMeta)))<EOL>
Test if the given type is a generic type. This includes Generic itself, but
    excludes special typing constructs such as Union, Tuple, Callable, ClassVar.
    Examples::

        is_generic_type(int) == False
        is_generic_type(Union[int, str]) == False
        is_generic_type(Union[int, T]) == False
        is_generic_type(ClassVar[List[int]]) == False
        is_generic_type(Callable[..., T]) == False

        is_generic_type(Generic) == True
        is_generic_type(Generic[T]) == True
        is_generic_type(Iterable[int]) == True
        is_generic_type(Mapping) == True
        is_generic_type(MutableMapping[T, List[int]]) == True
        is_generic_type(Sequence[Union[str, bytes]]) == True