To prevent circular imports, this extends isinstance()
    by checking also if `value` has a particular class name (or inherits from a
    particular class name). This check is safe in that an AttributeError is not
    raised in case `value` doesn't have a __class__ attribute.

def safe_isinstance(value, types=None, class_names=None):
    """To prevent circular imports, this extends isinstance()
    by checking also if `value` has a particular class name (or inherits from a
    particular class name). This check is safe in that an AttributeError is not
    raised in case `value` doesn't have a __class__ attribute.
    """
    # inspect is being imported here because I seriously doubt
    # that this function will be used outside of the type
    # checking below.
    import inspect
    result = False
    if types is not None:
        result = result or isinstance(value, types)
    if class_names is not None and not result:
        # this doesn't work with inheritance, but normally
        # either the class will already be imported within the module,
        # or the class doesn't have any subclasses. For example: PropertySet
        if isinstance(class_names, basestring):
            class_names = [class_names]
        # this is the part that makes it "safe".
        try:
            base_names = [class_.__name__ for class_ in inspect.getmro(value.__class__)]
            for name in class_names:
                if name in base_names:
                    return True
        except AttributeError:
            pass
    return result