import inspect
from collections import Mapping, Iterable


def is_generator(obj):
    """Return True if ``obj`` is a generator
    """
    return inspect.isgeneratorfunction(obj) or inspect.isgenerator(obj)


def is_iterable_but_not_string(obj):
    """Return True if ``obj`` is an iterable object that isn't a string."""
    return (
        (isinstance(obj, Iterable) and not hasattr(obj, "strip"))
        or is_generator(obj)
    )


def is_indexable_but_not_string(obj):
    """Return True if ``obj`` is indexable but isn't a string."""
    return not hasattr(obj, "strip") and hasattr(obj, "__getitem__")


def is_collection(obj):
    """
    Return True if ``obj`` is a collection type,
    e.g list, tuple, queryset.
    """
    return is_iterable_but_not_string(obj) and not isinstance(obj, Mapping)

import inspect
from collections import Mapping, Iterable


def is_generator(obj):
    """Return True if ``obj`` is a generator
    """
    return inspect.isgeneratorfunction(obj) or inspect.isgenerator(obj)


def is_iterable_but_not_string(obj):
    """Return True if ``obj`` is an iterable object that isn't a string."""
    return (
        (isinstance(obj, Iterable) and not hasattr(obj, "strip"))
        or is_generator(obj)
    )


def is_indexable_but_not_string(obj):
    """Return True if ``obj`` is indexable but isn't a string."""
    return not hasattr(obj, "strip") and hasattr(obj, "__getitem__")


def is_collection(obj):
    """
    Return True if ``obj`` is a collection type,
    e.g list, tuple, queryset.
    """
    return is_iterable_but_not_string(obj) and not isinstance(obj, Mapping)


def is_instance_or_subclass(val, class_):
    """Return True if ``val`` is either a subclass or instance of ``class_``."""
    try:
        return issubclass(val, class_)
    except TypeError:
        return isinstance(val, class_)

Add helper to check instance and subclass
Add helper to check instance and subclass

  import inspect
  from collections import Mapping, Iterable
  
  
  def is_generator(obj):
      """Return True if ``obj`` is a generator
      """
      return inspect.isgeneratorfunction(obj) or inspect.isgenerator(obj)
  
  
  def is_iterable_but_not_string(obj):
      """Return True if ``obj`` is an iterable object that isn't a string."""
      return (
          (isinstance(obj, Iterable) and not hasattr(obj, "strip"))
          or is_generator(obj)
      )
  
  
  def is_indexable_but_not_string(obj):
      """Return True if ``obj`` is indexable but isn't a string."""
      return not hasattr(obj, "strip") and hasattr(obj, "__getitem__")
  
  
  def is_collection(obj):
      """
      Return True if ``obj`` is a collection type,
      e.g list, tuple, queryset.
      """
      return is_iterable_but_not_string(obj) and not isinstance(obj, Mapping)
  
+ 
+ def is_instance_or_subclass(val, class_):
+     """Return True if ``val`` is either a subclass or instance of ``class_``."""
+     try:
+         return issubclass(val, class_)
+     except TypeError:
+         return isinstance(val, class_)
+ 
Add helper to check instance and subclass
## Code Before:
import inspect
from collections import Mapping, Iterable


def is_generator(obj):
    """Return True if ``obj`` is a generator
    """
    return inspect.isgeneratorfunction(obj) or inspect.isgenerator(obj)


def is_iterable_but_not_string(obj):
    """Return True if ``obj`` is an iterable object that isn't a string."""
    return (
        (isinstance(obj, Iterable) and not hasattr(obj, "strip"))
        or is_generator(obj)
    )


def is_indexable_but_not_string(obj):
    """Return True if ``obj`` is indexable but isn't a string."""
    return not hasattr(obj, "strip") and hasattr(obj, "__getitem__")


def is_collection(obj):
    """
    Return True if ``obj`` is a collection type,
    e.g list, tuple, queryset.
    """
    return is_iterable_but_not_string(obj) and not isinstance(obj, Mapping)

## Instruction:
Add helper to check instance and subclass
## Code After:
import inspect
from collections import Mapping, Iterable


def is_generator(obj):
    """Return True if ``obj`` is a generator
    """
    return inspect.isgeneratorfunction(obj) or inspect.isgenerator(obj)


def is_iterable_but_not_string(obj):
    """Return True if ``obj`` is an iterable object that isn't a string."""
    return (
        (isinstance(obj, Iterable) and not hasattr(obj, "strip"))
        or is_generator(obj)
    )


def is_indexable_but_not_string(obj):
    """Return True if ``obj`` is indexable but isn't a string."""
    return not hasattr(obj, "strip") and hasattr(obj, "__getitem__")


def is_collection(obj):
    """
    Return True if ``obj`` is a collection type,
    e.g list, tuple, queryset.
    """
    return is_iterable_but_not_string(obj) and not isinstance(obj, Mapping)


def is_instance_or_subclass(val, class_):
    """Return True if ``val`` is either a subclass or instance of ``class_``."""
    try:
        return issubclass(val, class_)
    except TypeError:
        return isinstance(val, class_)
